mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Compare commits
681 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 |
410
CONTRIBUTORS
410
CONTRIBUTORS
@ -275,7 +275,7 @@ Aaron Holtzman
|
||||
Wolfgang Henselmann-Weiss <Wolfgang_Henselmann@betaresearch.de>
|
||||
for fixing calculating the timeout value in cFile::FileReady()
|
||||
|
||||
Uwe Scheffler <linux_dvb@uni.de>
|
||||
Uwe Scheffler <scheffler.u@web.de>
|
||||
for his help in keeping 'channels.conf.cable' and 'channels.conf.terr' up to date
|
||||
for helping to test new DVB-T handling
|
||||
for reporting a bug in switching the video format in the Setup/DVB menu
|
||||
@ -283,6 +283,9 @@ Uwe Scheffler <linux_dvb@uni.de>
|
||||
for reporting a problem in handling the PrimaryLimit when requesting a device for
|
||||
live viewing
|
||||
for reporting a black screen while a "Recording started" message is displayed
|
||||
for reporting a problem with the lock on the Channels list in cDisplayChannel still
|
||||
being held when Flush() was called
|
||||
for reporting a problem with failed tuning in SCR systems
|
||||
|
||||
Matjaz Thaler <matjaz.thaler@guest.arnes.si>
|
||||
for improving AC3 decoding when replaying DVDs
|
||||
@ -715,6 +718,9 @@ Oliver Endriss <o.endriss@gmx.de>
|
||||
for suggesting to ignore channels with an RID that is not 0 when checking for obsolete
|
||||
channels
|
||||
for fixing a possible stack overflow in cListBase::Sort()
|
||||
for reporting a crash when deleting a recording
|
||||
for reporting a problem with sluggish setting of editing marks and a jumping progress
|
||||
display with very short recordings
|
||||
|
||||
Reinhard Walter Buchner <rw.buchner@freenet.de>
|
||||
for adding some satellites to 'sources.conf'
|
||||
@ -1198,6 +1204,9 @@ Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>
|
||||
for the "binary skip" patch
|
||||
for adding support for LCN (Logical Channel Numbers)
|
||||
for suggesting to change the naming of "binary skip mode" to "adaptive skip mode"
|
||||
for adding a Status parameter to the interface of cDevice::SignalStats() and
|
||||
cDvbDevice::SignalStats()
|
||||
for reporting a possible crash when scaling bitmaps with very small factors
|
||||
|
||||
Ralf Klueber <ralf.klueber@vodafone.com>
|
||||
for reporting a bug in cutting a recording if there is only a single editing mark
|
||||
@ -1217,6 +1226,9 @@ Peter Bieringer <pb@bieringer.de>
|
||||
for suggesting to ignore lines tagged with '#' in the 'info.vdr' file of a recording
|
||||
for reporting a problem with the backslash ('\') in parameters when executing
|
||||
external commands
|
||||
for making the functions cRecordingInfo::SetData() and cRecordingInfo::SetAux() public
|
||||
for adding some missing user command calls for copying, renaming and moving recordings
|
||||
for fixing scaling subtitles with anti-aliasing
|
||||
|
||||
Alexander Damhuis <ad@phonedation.de>
|
||||
for reporting problems when deleting a timer that is currently recording
|
||||
@ -1844,6 +1856,7 @@ Lucian Muresan <lucianm@users.sourceforge.net>
|
||||
for exporting some libsi functions
|
||||
for suggesting to add functions to cDevice that allow derived output devices to
|
||||
implement scaling the video to a given size and location
|
||||
for sorting sources.conf by continuous azimuth
|
||||
|
||||
Mattias Grönlund <Mattias@Gronlund.net>
|
||||
for pointing out a missing cleanup at program exit in case there is a problem
|
||||
@ -2062,6 +2075,8 @@ Ville Skytt
|
||||
for reporting a possible NULL pointer dereference in cCiSession::SendData()
|
||||
for reporting a superfluous assignment in cPipe::Open()
|
||||
for avoiding unnecessary pkg-config warnings in plugin Makefiles
|
||||
for fixing building VDR with systemd >= 230
|
||||
for avoiding some duplicate code and unnecessary work in nit.c
|
||||
|
||||
Steffen Beyer <cpunk@reactor.de>
|
||||
for fixing setting the colored button help after deleting a recording in case the next
|
||||
@ -2109,6 +2124,10 @@ Martin Wache <M.Wache@gmx.net>
|
||||
device, which avoids a busy loop on very fast machines
|
||||
for fixing a possible crash when loading an invalid XPM file
|
||||
for suggesting to speed up anti-aliased font rendering by caching the blend indexes
|
||||
for extending the option "Setup/Miscellaneous/Show channel names with source" to
|
||||
"type" or "full"
|
||||
for making the "Channels" menu indicate whether a channel is encrypted or a radio
|
||||
channel
|
||||
|
||||
Matthias Lenk <matthias.lenk@amd.com>
|
||||
for reporting an out-of-bounds memory access with audio language ids
|
||||
@ -2168,8 +2187,9 @@ Hardy Flor <HFlor@web.de>
|
||||
|
||||
Harald Milz <hm@seneca.muc.de>
|
||||
for his CUTR patch, which was used as a base to implement the SVDRP command EDIT
|
||||
for reporting a bug in parsing the '-l' command line option
|
||||
|
||||
Marko Mäkelä <marko.makela@hut.fi>
|
||||
Marko Mäkelä <marko.makela@iki.fi>
|
||||
for making repeat keys be ignored when waiting for a keypress to cancel an operation
|
||||
for reporting that a menu was automatically closed when a replay ends
|
||||
for suggesting to ignore k_Repeat when deciding whether the same key has been
|
||||
@ -2180,6 +2200,18 @@ Marko M
|
||||
for suggesting to simplify some conditional expressions in skinlcars.c and skinsttng.c
|
||||
for reporting some uninitialized item area coordinates in cSkinLCARSDisplayMenu
|
||||
for reporting a problem with the video directory not being set correctly with --edit
|
||||
for reporting a compiler warning about the use of strncpy() in strreplace()
|
||||
for adding support for kernel based LIRC driver
|
||||
for reporting a possible heap-use-after-free in cDvbTuner::Action()
|
||||
for reporting a flaw in initializing cDvbPlayerControl and cTransferControl
|
||||
for reporting a possible call to poll() in cSectionHandler::Action() without any
|
||||
filters
|
||||
for avoiding the memcpy() call in cGlyph::cGlyph() if the bitmap is empty
|
||||
for avoiding unnecessary processing in cDvbSubtitleConverter::FinishPage() if there
|
||||
are no areas
|
||||
for avoiding a zero sized array in cDevice::GetDevice()
|
||||
for reporting a crash when deleting a recording that is currently being edited, and
|
||||
then immediately deleting the edited version, too
|
||||
|
||||
Patrick Rother <krd-vdr@gulu.net>
|
||||
for reporting a bug in defining timers that only differ in the day of week
|
||||
@ -2323,6 +2355,7 @@ Andr
|
||||
for reporting a bug in selecting the last replayed recording in the Recordings menu
|
||||
in case there are folders and plain recordings with names that differ only in
|
||||
non-alphanumeric characters
|
||||
for reporting a problem with permanently looping through PMT PIDs on a SatIP receiver
|
||||
|
||||
Jürgen Schilling <juergen_schilling@web.de>
|
||||
for reporting that color buttons were displayed in the recording info menu if it
|
||||
@ -2424,6 +2457,23 @@ Christoph Haubrich <christoph1.haubrich@arcor.de>
|
||||
"Edit recording" menu
|
||||
for suggesting to add a confirmation before renaming a recording to its folder name
|
||||
for reporting a problem with data loss in case renaming a recording fails
|
||||
for adding support for HEVC-video and AC-4-audio
|
||||
for implementing anti-aliasing for cPixmap::DrawSlope() and cPixmap::DrawEllipse()
|
||||
for reporting an unnecessary double call to Display() in cMenuRecording::RefreshRecording()
|
||||
for reporting too much memory being allocated in the cImage constructors
|
||||
for making the 'Edit path' dialog also show the total size of all recordings in that path
|
||||
for suggesting to make cRecordingInfo::Errors() return -1 for old recordings, and
|
||||
reporting a missing 'const'
|
||||
for reporting that the edited recording is not deleted in case of an error
|
||||
for reporting missing '0x09=H.265 video, 0x19 = AC4 audio' in vdr.5
|
||||
for reporting a problem with the call to EpgHandlers.EndSegmentTransfer()
|
||||
for fixing handling zero bytes in cH264Parser
|
||||
for implementing parsing frame rate and image size for MPEG2, H.264 and H.265
|
||||
for reporting a bug in generating the index file in the cutter
|
||||
for adding the frame width, height, scan type and aspect ratio of a recording to the 'F'
|
||||
tag of the 'info' file
|
||||
for adding a workaround in detecting frame height for channels with wrong crop parameters
|
||||
for reporting duplicate component entries in the info of an ongoing recording
|
||||
|
||||
Pekka Mauno <pekka.mauno@iki.fi>
|
||||
for fixing cSchedule::GetFollowingEvent() in case there is currently no present
|
||||
@ -2474,6 +2524,13 @@ Tobias Grimm <tobias.grimm@e-tobi.net>
|
||||
numbers use a decimal point
|
||||
for adding dependency on 'i18n' to 'install-i18n' in the VDR Makefile
|
||||
for adding a manual page for 'svdrpsend'
|
||||
for adding a missing dependency to the Makefile to avoid error messages in the
|
||||
clean-plugins target
|
||||
for adding optional verbose output to the libsi Makefile
|
||||
for making the call to pkg_config configurable via the PKG_CONFIG macro
|
||||
for fixing a typo in svdrp.c
|
||||
for suggesting to add CPPFLAGS to CXXFLAGS to allow extra preprocessor flags to be
|
||||
given when doing make
|
||||
|
||||
Helge Lenz <h.lenz@gmx.de>
|
||||
for reporting a bug in setting the 'Delta' parameter when calling the shutdown
|
||||
@ -2495,6 +2552,50 @@ Nino Gerbino <ngerb@interfree.it>
|
||||
Markus Ehrnsperger <markus.ehrnsperger@googlemail.com>
|
||||
for reporting a problem with missing 'INCLUDES += -I$(DVBDIR)/include' in an existing
|
||||
Make.config
|
||||
for reporting a bug in error handling when loading a plugin
|
||||
for reporting a possible crash in cIndexFile::GetClosestIFrame()
|
||||
for reporting a missing 'const' in cTimers::GetTimerForEvent()
|
||||
for suggesting to add a chapter about locking to PLUGINS.html
|
||||
for fixing unnecessary interruption of ongoing recordings if timers avoided the
|
||||
transfer mode receiver device
|
||||
for reporting broken video data streams on systems without output device when switching
|
||||
live channel to a different transponder while recording
|
||||
for fixing a possible crash in cDevice::StopSectionHandler()
|
||||
for making using a dummy OSD if no OSD provider is available not be considered an error
|
||||
any more
|
||||
for removing syslog calls in child process after fork()
|
||||
for adding the move constructor to cString for better performance
|
||||
for fixing handling primary device on headless systems
|
||||
for adding a 15 second grace period before actually stopping a VPS timer
|
||||
for making the primary device no longer start unnecessary threads if it doesn't have
|
||||
a decoder
|
||||
for improving handling present/following data for VPS timers
|
||||
for making logging event status changes also show the previous status
|
||||
for making a device always being kept occupied if a timer is in VPS margin or needs the
|
||||
transponder
|
||||
for suggesting to enable unused devices to be put into a power save mode
|
||||
for a patch that was used to implement power save mode for cDvbDevice
|
||||
for suggesting to add 'lnbPowerTurnedOn = false' to cDvbTuner::ProvidesFrontend()
|
||||
for reporting a crash in strreplace() for multiple replacements with strings of
|
||||
different lengths
|
||||
for suggesting to add the lines from 'Fixed a timeout in cDvbDevice while tuning after
|
||||
the frontend has been reopened' to cDvbTuner::ProvidesFrontend()
|
||||
for improving the error message when closing a frontend
|
||||
for reporting a problem in cSchedule::Sort(), in case hasRunning was true, but there
|
||||
was no event with RunningStatus() >= SI::RunningStatusPausing
|
||||
for reporting problem with duplicate events if they are moved to a lower table ID and
|
||||
at the same time get a new event ID
|
||||
for reporting a bug in handling negative values in cSource::Position() on
|
||||
systems where 'int' is 64 bit
|
||||
for suggesting a fix for expiring of one-time VPS timers in case there is more than
|
||||
one event with the same VPS time
|
||||
for fixing handling margins for timers that are not VPS controlled and not spawned
|
||||
for implementing cStatus::OsdItem2() with the information whether the item is selectable
|
||||
for reporting an improper call of cStatus::OsdCurrentItem() before cStatus::OsdItem2()
|
||||
for fixing unnecessary calls to DisplayCurrent() for editable menu items
|
||||
for implementing cStatus::OsdCurrentItem2() with the index of the current item
|
||||
for adding missing calls to cStatus::MsgOsdStatusMessage() and implementing
|
||||
cStatus::OsdStatusMessage2() with the type of the message
|
||||
|
||||
Werner Färber <w.faerber@gmx.de>
|
||||
for reporting a bug in handling the cPluginManager::Active() result when pressing
|
||||
@ -2612,6 +2713,15 @@ J
|
||||
for adding HandledExternally() to the EPG handler interface
|
||||
for adding IsUpdate() to the EPG handler interface
|
||||
for adding Begin/EndSegmentTransfer() to the EPG handler interface
|
||||
for making cEpgHandlers::BeginSegmentTransfer() boolean
|
||||
for suggesting to change tEventID back to u_int32_t
|
||||
for adding the 'aux' member to cEvent
|
||||
for reporting a possible deadlock when quickly zapping through encrypted channels
|
||||
for a patch that was used to implement cStatus::MarksModified()
|
||||
for suggesting to no longer log unaligned marks in cMarks::Align()
|
||||
for reporting some warnings from g++ 7.2.0 regarding fixed buffer sizes in
|
||||
cMenuEditTimeItem::Set() and cCountdown::Update()
|
||||
for fixing symmetry of Begin/EndSegmentTransfer() calls in cEIT::cEIT()
|
||||
|
||||
Peter Pinnau <vdr@unterbrecher.de>
|
||||
for reporting that 'uint32_t' requires including stdint.h in font.h on some systems
|
||||
@ -2718,10 +2828,38 @@ Benjamin Hess <benjamin.h@gmx.ch>
|
||||
for enhancing the SVDRP command CLRE to allow clearing the EPG data of a particular
|
||||
channel
|
||||
|
||||
Winfried Koehler <w_koehl@gmx.de>
|
||||
Winfried Köhler <nvdec@quantentunnel.de>
|
||||
for fixing finding new transponders
|
||||
for fixing wrong value for TableIdBAT in libsi/si.h
|
||||
for reporting a compiler warning in calculations involving FramesPerSecond()
|
||||
for making several code modifications to avoid compiler warnings
|
||||
for improving the description of the transponder parameters in vdr.5
|
||||
for reporting a necessary fix in the description of cReceiver in PLUGINS.html,
|
||||
regarding detaching a receiver from its device before deleting it
|
||||
for fixing some copy&paste errors in PLUGINS.html
|
||||
for fixing the size of cChannel::dtypes[]
|
||||
for adding a device hook for detecting whether a device provides EIT data
|
||||
for improving deleting plugins in case the plugin uses its own memory management
|
||||
for reporting a bug in handling newline characters in ci.c's CopyString()
|
||||
for reporting a bug in checking the return value of the Open() call in
|
||||
cFileName::SetOffset()
|
||||
for adding initialization of cDvbFrontend::frontendInfo
|
||||
for improving handling missing VDRPluginDestroyer()
|
||||
for fixing a compiler warning
|
||||
for fixing handling $(PKG_CONFIG) in newplugin
|
||||
for using __cplusplus instead of DISABLE_TEMPLATES_COLLIDING_WITH_STL, and using
|
||||
std::min(), std::max() and std::swap() is available
|
||||
for adding some missing "AUTO" values to vdr.5
|
||||
for fixing default values for DVB-T
|
||||
for adding missing rounding when dividing frequencies in processing the NIT
|
||||
for suggesting to add note about not messing with event ids in EPG handlers
|
||||
for adding a missing initialization of cChannel::nameSourceMode
|
||||
for suggesting to make APIVERSION a simple number, independent from VDRVERSION
|
||||
for reporting a compiler warning with gcc 14.1.0
|
||||
for suggesting to remove defining DEPRECATED_* macros with value 0, because this
|
||||
is the preprocessor's default
|
||||
for suggesting a fix for handling negative values in cSource::Position() on
|
||||
systems where 'int' is 64 bit
|
||||
|
||||
Hans-Werner Hilse <hilse@web.de>
|
||||
for adding the command line option --userdump to enable core dumps in case VDR
|
||||
@ -2788,13 +2926,6 @@ Michael Nork <mnork0@gmx.net>
|
||||
binary distributions to have full control over whether or not to use the --vfat
|
||||
option at runtime
|
||||
|
||||
Winfried Köhler <w_koehl@gmx.de>
|
||||
for fixing wrong value for TableIdBAT in libsi/si.h
|
||||
for making several code modifications to avoid compiler warnings
|
||||
for improving the description of the transponder parameters in vdr.5
|
||||
for reporting a necessary fix in the description of cReceiver in PLUGINS.html,
|
||||
regarding detaching a receiver from its device before deleting it
|
||||
|
||||
Igor M. Liplianin <liplianin@tut.by>
|
||||
for a patch that was used to convert VDR to the S2API driver API
|
||||
|
||||
@ -2818,6 +2949,20 @@ Johann Friedrichs <johann.friedrichs@web.de>
|
||||
for fixing loading the setup.conf file in case a parameter contains the '#' character
|
||||
for reporting that the "Resume" button in the main menu was active even if the
|
||||
respective recording did not exist
|
||||
for fixing a double deletion of a cTimer in case HandleRemoteModifications() returned
|
||||
false
|
||||
for reporting an invalid lock sequence in the epgsearch plugin, which turned out to
|
||||
be an abandoned member of class cSchedulesLock
|
||||
for fixing handling VPS events outside the LingerLimit, which could cause recordings to
|
||||
stop prematurely
|
||||
for fixing handling timers during the change from DST to winter time
|
||||
for fixing a possible crash with plugins that retrieve player information after a
|
||||
replay has been stopped, but before the replay control has been destroyed
|
||||
for reporting a problem in processing SVDRP client responses in case the caller doesn't
|
||||
want the actual response strings
|
||||
for reporting a bug in handling the tfRecording flag in the SVDRP commands MODT and UPDT
|
||||
for adding a missing '-D' to the 'plugins' target of the Makefile
|
||||
for adding code for the 'qks' audio track
|
||||
|
||||
Timo Helkio <timolavi@mbnet.fi>
|
||||
for reporting a hangup when replaying a TS recording with subtitles activated
|
||||
@ -2844,6 +2989,9 @@ Derek Kelly <user.vdr@gmail.com>
|
||||
for suggesting to add ARGSDIR to the ONEDIR section of Make.config.template
|
||||
for suggesting to change the naming of "binary skip mode" to "adaptive skip mode"
|
||||
for suggesting to make the -u option also accept a numerical user id
|
||||
for reporting a problem with abs() in gcc6+ when called with an unsigned variable
|
||||
for reporting a deadlock after the fix for a race between SVDRP CHAN and
|
||||
cDevice::HasProgramme()
|
||||
|
||||
Marcel Unbehaun <frostworks@gmx.de>
|
||||
for adding cRecordingInfo::GetEvent()
|
||||
@ -2875,6 +3023,14 @@ Manuel Reimer <Manuel.Reimer@gmx.de>
|
||||
order to avoid discontinuities
|
||||
for setting the environment variables HOME, USER, LOGNAME and SHELL accordingly
|
||||
when switching to a less privileged user id
|
||||
for reporting a bug in moving channels between number groups in SVDRP's MOVC command
|
||||
for fixing compatibility with current versions of glibc
|
||||
for suggesting to make the SVDRP command DELC accept a channel id
|
||||
for reporting a crash in the SVDRP command CLRE in case a non-existing channel
|
||||
number is given
|
||||
for reporting that LSTE doesn't work after PUTE in case a channel didn't already
|
||||
have EPG data
|
||||
for suggesting to make APIVERSION a simple number, independent from VDRVERSION
|
||||
|
||||
Rene van den Braken <rene@vandenbraken.name>
|
||||
for reporting a bug in writing the PCR pid into the PMT in
|
||||
@ -2924,6 +3080,11 @@ Lars Hanisch <dvb@flensrocker.de>
|
||||
for making VDR read command line options from *.conf files in /etc/vdr/conf.d
|
||||
for adding a missing backslash to the help text of the SVDRP command MOVR
|
||||
for fixing a memory leak in case of broken Extended Event Descriptors
|
||||
for adding a 'const' version of cTimers::GetTimer()
|
||||
for fixing a typo in the description of cTimers::GetTimersRead()
|
||||
for suggesting to use dynamic buffering in handling CA descriptors to avoid a
|
||||
possible buffer overflow
|
||||
for suggesting to make APIVERSION a simple number, independent from VDRVERSION
|
||||
|
||||
Alex Lasnier <alex@fepg.org>
|
||||
for adding tuning support for ATSC devices
|
||||
@ -3008,6 +3169,11 @@ Frank Neumann <fnu@yavdr.org>
|
||||
for adding support for "Satellite Channel Routing" (SCR) according to EN50607 ("JESS")
|
||||
for suggesting to make the Setup/CAM menu display which device an individual CAM
|
||||
is currently assigned to
|
||||
for reporting a problem with the default return value of cEpgHandler::BeginSegmentTransfer()
|
||||
in derived classes that don't implement this function
|
||||
for reporting uninitialized variable SdWatchdog in vdr.c
|
||||
for suggesting to use readdir() instead of readdir_r(), if GLIBC version 2.24 or
|
||||
newer is used
|
||||
|
||||
Gerald Dachs <vdr@dachsweb.de>
|
||||
for reporting a problem with checking for minimum line length of 21 characters in
|
||||
@ -3073,6 +3239,10 @@ Frank Niederwipper <f.niederwipper@gmail.com>
|
||||
Chris Mayo <aklhfex@gmail.com>
|
||||
for reporting a problem with detecting frames on radio channels
|
||||
for fixing the link to "svdrpsend (1)" in the vdr.1 man page
|
||||
for updating links in the INSTALL file
|
||||
for reporting double slashes in file names processed with AddDirectory()
|
||||
for using the 'example' macro in vdr.5
|
||||
for fixing the install target in case of multiple jobs
|
||||
|
||||
Dominic Evans <oldmanuk@gmail.com>
|
||||
for making the SVDRP command LSTC accepts channel IDs
|
||||
@ -3162,6 +3332,7 @@ Oliver Schinagl <oliver@schinagl.nl>
|
||||
Andrey Pridvorov <ua0lnj@bk.ru>
|
||||
for reporting a problem with detecting frames in H.264 video, and pointing towards
|
||||
a better way of doing it
|
||||
for updating the Russian OSD texts
|
||||
|
||||
Jens Vogel <jens.vogel@akjv.de>
|
||||
for suggesting to make cPatPmtParser::ParsePmt() also recognize stream type 0x81
|
||||
@ -3203,6 +3374,16 @@ Mike Hay <mike.hay@linenshorts.com>
|
||||
Stefan Hofmann <stefan.hofmann@t-online.de>
|
||||
for suggesting to implement support for remote controls that only have a combined
|
||||
"Play/Pause" key instead of separate keys for "Play" and "Pause"
|
||||
for a fix for compilers that don't like non-constant format strings
|
||||
for suggesting to implement jumping between errors while replaying a recording
|
||||
for adding vdrrootdir and incdir to vdr.pc
|
||||
for fixing some typos in the translation files
|
||||
for adding 1 to Utf8BufSize() for worst case
|
||||
for adding a header to the backtrace
|
||||
for adding parameter checks to strn0cpy()
|
||||
for making the info files of recordings only be re-read if they have been modified
|
||||
for reporting missing setting the file name of the info file after renaming a recording
|
||||
for adding '~' to the list of delimiters in cTextWrapper
|
||||
|
||||
Stefan Blochberger <Stefan.Blochberger@gmx.de>
|
||||
for suggesting to automatically display the progress display whenever replay of a
|
||||
@ -3225,6 +3406,7 @@ Malte Forkel <malte.forkel@berlin.de>
|
||||
|
||||
Marc Perrudin <vdr@ekass.net>
|
||||
for translating OSD texts to the French language
|
||||
for adding support for the systemd watchdog
|
||||
|
||||
Bernard Jaulin <bernard.jaulin@gmail.com>
|
||||
for translating OSD texts to the French language
|
||||
@ -3241,6 +3423,37 @@ Matthias Senzel <matthias.senzel@t-online.de>
|
||||
for reporting a bug in switching channels in the Schedule menu after going through
|
||||
various Now and Schedule menus for different channels
|
||||
for the "jumpingseconds" patch
|
||||
for reporting a bug in drawing very long menu titles in the LCARS skin
|
||||
for reporting and helping to debug a crash when stopping VDR
|
||||
for reporting a crash when moving a recording between different volumes
|
||||
for reporting a deadlock when moving a folder containing several recordings between
|
||||
different volumes
|
||||
for fixing a lengthy write lock on the Recordings list in case of moving a folder with
|
||||
more than one recording
|
||||
for implementing the parameter "OSD/Sorting direction for recordings"
|
||||
for suggesting to stay in the original folder when moving a recording to a different
|
||||
folder
|
||||
for reporting problem with locking the Recordings list in the cutting process
|
||||
for suggesting to change the log message ""ERROR: copying directory '%s' to '%s' ended
|
||||
prematurely" from "error" to "info"
|
||||
for suggesting to allow opening a folder when selecting a folder for a recording or
|
||||
timer, even if it doesn't contain any subfolders
|
||||
for reporting a possible locking problem in cMenuPathEdit::ApplyChanges() when the
|
||||
lock is held while the error message is displayed
|
||||
for reporting that the info of a newly edited recording was not available immediately
|
||||
after starting the editing process
|
||||
for reporting a problem with setting the initial offset of the cursor in a list menu
|
||||
for reporting a high CPU load during replay with active progress display
|
||||
for reporting that the lock on the Channels list in cDisplayChannel was still held
|
||||
when Flush() was called
|
||||
for reporting that if an error occurs while recording, the respective entry in the list
|
||||
of recordings was not updated immediately
|
||||
for fixing restoring the volume at program start
|
||||
for fixing height calculation in progress display
|
||||
for fixing an unnecessary double display of the current menu item in page up/down
|
||||
for fixing an unnecessary double display of menu items in the Recordings menu
|
||||
for reporting a bug in handling cSkinDisplayMenu::GetTextAreaFont()
|
||||
for reporting characters being cut off while editing in the LCARS skin
|
||||
|
||||
Marek Nazarko <mnazarko@gmail.com>
|
||||
for translating OSD texts to the Polish language
|
||||
@ -3322,6 +3535,21 @@ Thomas Reufer <thomas@reufer.ch>
|
||||
ViewPort and DrawPort
|
||||
for suggesting to reduce the priority of the "video directory scanner" thread
|
||||
for making the 'newplugin' script create the 'po' subdirectory for translations
|
||||
for suggesting to add a note to the description of cFont::Size(), regarding possible
|
||||
differences between it and cFont::Height()
|
||||
for making the cPlayer member functions FramesPerSecond, GetIndex and GetReplayMode
|
||||
'const'
|
||||
for fixing resuming replay at a given position, which was off by one frame
|
||||
for improving handling frame numbers to have a smoother progress display during
|
||||
replay of recordings with B-frames
|
||||
for fixing replaying recordings to their very end, if they don't end with an I-frame
|
||||
for implementing a frame parser for H.265 (HEVC) recordings
|
||||
for adding cFont::Width(void) to get the default character width and allow stretched
|
||||
font drawing in high level OSDs
|
||||
for fixing regenerating the index of audio recordings
|
||||
for implementing the SVDRP commands 'LSTD' and 'PRIM'
|
||||
for adding some comments regarding font height
|
||||
for reporting a possible problem with plugins calling IsOpen() in ~cDisplayChannel()
|
||||
|
||||
Eike Sauer <EikeSauer@t-online.de>
|
||||
for reporting a problem with channels that need more than 5 TS packets for detecting
|
||||
@ -3349,6 +3577,9 @@ Tony Houghton <h@realh.co.uk>
|
||||
Christian Winkler <winkler_chr@yahoo.de>
|
||||
for reporting a problem with transfer mode on full featured DVB cards for encrypted
|
||||
channels that have no audio pid
|
||||
for reporting a problem when selecting a device/CAM combination for live viewing, if
|
||||
the CAM that is known to decrypt the requested channel can not be assigned to the
|
||||
primary device
|
||||
|
||||
Dietmar Spingler <d_spingler@gmx.de>
|
||||
for reporting a problem that led to a fix in detaching receivers from devices in case
|
||||
@ -3359,6 +3590,11 @@ Dietmar Spingler <d_spingler@gmx.de>
|
||||
for suggesting to provide a way of using no DVB devices at all
|
||||
for suggesting that the -V and -h options should list the plugins in alphabetical order
|
||||
for suggesting to implement the setup option "Recording/Record key handling"
|
||||
for suggesting to cache the channel/CAM relations in the file 'cam.data'
|
||||
for suggesting to optionally list the channels with channel ids in the SVDRP command LSTC
|
||||
for suggesting to include the channel ID in log messages about switching channels
|
||||
for reporting a problem with the SVDRP command CHAN while the channel display is open
|
||||
for suggesting to automatically close the CAM menu when the current channel is switched
|
||||
|
||||
Stefan Schallenberg <infos@nafets.de>
|
||||
for adding the functions IndexOf(), InsertUnique(), AppendUnique() and RemoveElement()
|
||||
@ -3367,6 +3603,10 @@ Stefan Schallenberg <infos@nafets.de>
|
||||
Claus Muus <email@clausmuus.de>
|
||||
for adding the new parameters "Setup/Miscellaneous/Volume steps" and
|
||||
".../Volume linearize"
|
||||
for reporting multiple recording entries in case a recording is started during the
|
||||
initial reading of the video directory
|
||||
for reporting that getting the lock for removing deleted recordings may fail if the
|
||||
disk is full
|
||||
|
||||
Dieter Ferdinand <dieter.ferdinand@gmx.de>
|
||||
for reporting a problem with jumping to an absolute position via the Red key in
|
||||
@ -3379,6 +3619,18 @@ Dieter Ferdinand <dieter.ferdinand@gmx.de>
|
||||
Jasmin Jessich <jasmin@anw.at>
|
||||
for modifying the CAM API so that it is possible to implement CAMs that can be freely
|
||||
assigned to any devices
|
||||
for writing the ddci2 plugin and for valuable input and help with testing and
|
||||
debugging MTD support
|
||||
for fixing selecting delivery system names in case of undefined indexes
|
||||
for fixing detecting the inclusion of STL header files in tools.h
|
||||
for help and suggestions when implementing debug output for checking the correct
|
||||
sequence of locking global lists
|
||||
for suggesting to use $(Q) to control Makefile verbosity
|
||||
for adding handling DEBUG to the Make.config.template file, in order to control
|
||||
code optimization
|
||||
for suggesting to change the macros used to control deprecated code or functions
|
||||
to numeric values (0 and 1), so that they can be controlled at compile time, without
|
||||
having to edit the actual source code
|
||||
|
||||
Martin Schirrmacher <schirrmie@gmail.com>
|
||||
for suggesting to provide a way for skin plugins to get informed about the currently
|
||||
@ -3393,6 +3645,13 @@ Stefan Herdler <herdler@gmx.de>
|
||||
too early
|
||||
for reporting a bug in using the default sort mode in a video directory without a
|
||||
".sort" file
|
||||
for reporting faulty memory handling in cString::Append()
|
||||
for adding failsafe defaults for 'make LCLBLD=1' to the Makefile
|
||||
for reporting the index file of a recording not being regenerated in case it is
|
||||
present, but empty
|
||||
for reporting a missing check for self-assignment in the move assignment operator
|
||||
for modifying handling channel names with source to make it thread safe
|
||||
for fixing setting T2 system ID from NIT
|
||||
|
||||
Tobias Faust <tobias.faust@gmx.de>
|
||||
for the original "jumpingseconds" patch
|
||||
@ -3428,3 +3687,134 @@ Janne P
|
||||
Stefan Pöschel <basic.master@gmx.de>
|
||||
for coding the AFFcleaner, parts of which were used to make the recorder skip empty
|
||||
adaptation field TS packets
|
||||
|
||||
Robert Hannebauer <vdr@hannebauer.org>
|
||||
for fixing an overflow of PIDs in a receiver
|
||||
for fixing opening the UDP port in peerdemo
|
||||
|
||||
Aitugan Sarbassov <isarbassov@gmail.com>
|
||||
for adding 'S58.5E Kazsat 3' to sources.conf
|
||||
|
||||
Sergey Chernyavskiy <glenvt18@gmail.com>
|
||||
for reporting truncated date/time strings in the skins on multi-byte UTF-8
|
||||
for adding a short sleep to cTSBuffer::Action() to avoid high CPU usage
|
||||
for making the SVDRP commands that deal with recordings use a unique id for each
|
||||
recording
|
||||
|
||||
Frank Richter <kulpstur@t-online.de>
|
||||
for adding 'S3W ABS-3A' to sources.conf
|
||||
|
||||
Daniel Scheller <d.scheller@gmx.net>
|
||||
for reporting a problem with detecting whether a CAM replies to queries, which didn't
|
||||
work on some systems since the implementation of RI_HOST_CONTROL
|
||||
|
||||
Onur Sentürk <onur@sentek.org>
|
||||
for making the MTD mapper avoid immediately reusing unique PIDs when switching channels
|
||||
for fixing handling shared CA pids
|
||||
for fixing handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting
|
||||
in "backwards compatibility mode" according to ETSI EN 300 468
|
||||
for pointing out some potentially mistakable code in cSectionHandler::SetStatus()
|
||||
for adding periodic calls to malloc_trim(0) to reduce memory consumption
|
||||
|
||||
Helmut Binder <cco@aon.at>
|
||||
for improving calculating signal strength and quality
|
||||
for fixing switching through encrypted channels with the Up/Down keys
|
||||
for deactivating MTD support if a non MCD capable CAM is inserted after removing
|
||||
a previously used CAM that is MCD capable
|
||||
for fixing accessing the actual frontend on multi frontend devices
|
||||
for fixing processing the last entry in the scan list of the EIT scanner
|
||||
for fixing processing transponder data in the NIT
|
||||
for fixing triggering the SDT filter when parsing the NIT
|
||||
for reporting a bug in processing SI::T2DeliverySystemDescriptor when typecasting it
|
||||
over an SI::ExtensionDescriptor
|
||||
for fixing mapping SIDs in MTD
|
||||
for fixing updating the checksum in the CA table after mapping EMM PIDs for MTD
|
||||
for fixing a compiler warning in ExchangeChars()
|
||||
for suggesting to add __attribute__((packed)) to tIndexPes and tIndexTs
|
||||
for helping with the implementation of retuning if the received transponder's SDT
|
||||
doesn't contain the expected values for NID and TID
|
||||
for adding the language code for Bulgarian
|
||||
for a patch that was used as a base for fixing handling multi part ExtendedEventDescriptors
|
||||
where only the first part contains information about the character table
|
||||
for suggesting to check and report whether the given value is valid when setting the
|
||||
override character table
|
||||
for adding codes for more languages and special audio tracks
|
||||
for adding cMtdCamSlot::TsPostProcess()
|
||||
for adding cMtdHandler::StopDecrypting()
|
||||
for adding support for detecting new channels broadcast in HEVC
|
||||
for adding support for detecting 'advanced codec digital radio sound service'
|
||||
for adding handling shared PMT pids and multiple PMT sections
|
||||
for changing the country code in the generated ParentalRatingDescriptor from 'DEU' to
|
||||
'902' to make it valid for all countries
|
||||
for adjusting device selection in GetDeviceForTransponder() to that in GetDevice()
|
||||
for adding CRC check of the CAT in cCaPidReceiver::Receive()
|
||||
for reporting that the 'else if' branch in cDevice::GetDeviceForTransponder() hasn't
|
||||
been active since version 1.7.29
|
||||
for fixing handling inactive shared CA pids
|
||||
for implementing handling multi packet CATs with MTD
|
||||
for adding checking the symbol rate to cDvbTuner::IsTunedTo(), which apparently got
|
||||
lost in version 1.7.13
|
||||
for adding a check for an empty command in cDvbTuner::GetSignalStats() to avoid a
|
||||
possible error message
|
||||
for initializing the status variable in cDvbTuner::GetFrontendStatus() and
|
||||
cDvbTuner::GetSignalStats() to avoid problems with drivers that don't do this
|
||||
for fixing "read incomplete section" errors
|
||||
for fixing generating the HashId in cEIT::cEIT()
|
||||
for fixing a bug in handling shared PMTs, where after the first pass not all SIDs of a
|
||||
PMT pid were checked any more
|
||||
for reporting a problem with PMT handling in case locking the Channels list times out
|
||||
for avoiding a lengthy lock on the Channels list when starting a recording
|
||||
for preventing switching devices for pattern timers
|
||||
for pointing out that cChannel::Transponder(void) is called very often
|
||||
for fixing flushing old data from the section handler
|
||||
for removing unused declaration of cDvbTuner::SetFrontendType()
|
||||
for fixing handling incomplete multi-packet CAT
|
||||
for fixing a memory leak in handling the NIT
|
||||
for reporting a possible memory leak in creating fonts
|
||||
for fixing a possible deadlock in cDevice::DetachAllReceivers()
|
||||
|
||||
Ulrich Eckhardt <uli@uli-eckhardt.de>
|
||||
for reporting a problem with shutdown after user inactivity in case a plugin is
|
||||
keeping the OSD open
|
||||
|
||||
Stian B. Barmen <stian@barmen.nu>
|
||||
for reporting missing EPG data on channels from Canal Digital Norway
|
||||
|
||||
Jürgen Schneider <jsffm@web.de>
|
||||
for reporting a possible discrepancy of the primary device number in the LSTD and
|
||||
PRIM commands
|
||||
for adding support for EAC3 audio from other sources
|
||||
for reporting a crash if a pattern timer spawns a timer that uses EPISODE and the
|
||||
event has no short text
|
||||
for reporting a bug in VPS handling when spawning a pattern timer, in case Setup.UseVps
|
||||
is false
|
||||
for reporting an endless spawning of pattern timers in case the spawned timer doesn't
|
||||
use VPS and fully overlaps a second event that is longer than the original one
|
||||
for reporting a missing EPISODE macro expansion in case the event doesn't yet have a
|
||||
short text when generating the pattern timer file name
|
||||
for reporting a problem with spawned timers jumping to the next event in case
|
||||
Setup.EPGLinger is very small
|
||||
|
||||
Stefan Verse <Verse@amotronics.de>
|
||||
for fixing an occasional black screen when switching channels
|
||||
|
||||
Jens Schleusener <Jens.Schleusener@fossies.org>
|
||||
for reporting several typos
|
||||
|
||||
Bernd Kuhls <bernd.kuhls@t-online.de>
|
||||
for fixing possible compilation errors with libjpeg
|
||||
|
||||
Ulf Grüne <ulf.gruene@t-online.de>
|
||||
for reporting the need for more than 15 modulation systems in cDevice::GetDevice()
|
||||
|
||||
Timo Weingärtner <timo@tiwe.de>
|
||||
for reporting an integer overflow in calculating the disk use percentage if there's
|
||||
more than 20TB of recordings
|
||||
|
||||
Jose Angel <joseangelpp@gmail.com>
|
||||
for reporting a bug in default values for DVB-T
|
||||
|
||||
Andreas Baierl <post@andreasbaierl.de>
|
||||
for implementing scaling images
|
||||
for reporting a problem in the progress display when switching from "pause" to
|
||||
"slow back"
|
||||
|
59
INSTALL
59
INSTALL
@ -1,7 +1,7 @@
|
||||
Installation of the Video Disk Recorder
|
||||
---------------------------------------
|
||||
|
||||
Version 2.2
|
||||
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.
|
||||
@ -104,13 +103,13 @@ hardware in your system, for instance:
|
||||
Plugin: Device:
|
||||
|
||||
dvbsddevice Full-Featured SD DVB cards (Fujitsu-Siemens Design)
|
||||
(comes with the VDR source)
|
||||
ftp://ftp.tvdr.de/vdr/Plugins
|
||||
dvbhddevice Full-featured HD DVB cards (Technotrend TT S2-6400)
|
||||
https://bitbucket.org/powARman/dvbhddevice
|
||||
rpihddevice Raspberry Pi
|
||||
http://projects.vdr-developer.org/git/vdr-plugin-rpihddevice.git
|
||||
https://projects.vdr-developer.org/git/vdr-plugin-rpihddevice.git
|
||||
|
||||
See http://linuxtv.org/vdrwiki/index.php/Output_devices for more.
|
||||
See https://linuxtv.org/vdrwiki/index.php/Output_devices for more.
|
||||
|
||||
Standard compliance
|
||||
-------------------
|
||||
@ -265,11 +264,10 @@ 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 "editing" and "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*
|
||||
@ -277,13 +275,16 @@ string parameters. The first parameter is one of
|
||||
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 "editing" and "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
|
||||
@ -316,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"
|
||||
;;
|
||||
|
190
MANUAL
190
MANUAL
@ -1,7 +1,7 @@
|
||||
Video Disk Recorder User's Manual
|
||||
---------------------------------
|
||||
|
||||
Version 2.2
|
||||
Version 2.7
|
||||
-----------
|
||||
|
||||
* Remote Control Keys
|
||||
@ -50,8 +50,8 @@ Version 2.2
|
||||
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.2
|
||||
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.2
|
||||
|
||||
* 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.2
|
||||
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
|
||||
|
||||
@ -477,6 +480,8 @@ Version 2.2
|
||||
"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
|
||||
@ -508,6 +513,140 @@ Version 2.2
|
||||
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
|
||||
@ -662,6 +801,13 @@ Version 2.2
|
||||
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
|
||||
@ -683,6 +829,16 @@ Version 2.2
|
||||
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
|
||||
@ -884,6 +1040,9 @@ Version 2.2
|
||||
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
|
||||
@ -1082,8 +1241,16 @@ Version 2.2
|
||||
connection after which the connection is automatically
|
||||
closed. Default is 300, a value of 0 means no timeout.
|
||||
|
||||
SVDRP peering = no Activates automatic connections between VDRs in the same
|
||||
network.
|
||||
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.
|
||||
@ -1113,7 +1280,7 @@ Version 2.2
|
||||
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
|
||||
@ -1140,10 +1307,11 @@ Version 2.2
|
||||
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 3.4 2015/02/09 09:58:45 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,14 +33,15 @@ 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
|
||||
@ -68,6 +75,8 @@ endif
|
||||
|
||||
### 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
|
||||
|
94
Makefile
94
Makefile
@ -4,23 +4,26 @@
|
||||
# See the main source file 'vdr.c' for copyright information and
|
||||
# how to reach the author.
|
||||
#
|
||||
# $Id: Makefile 3.6 2015/02/09 12:28:24 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,6 +31,14 @@ 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
|
||||
@ -35,13 +46,14 @@ 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
|
||||
|
||||
@ -52,6 +64,15 @@ DOXYFILE = Doxyfile
|
||||
|
||||
-include Make.config
|
||||
|
||||
# Output control
|
||||
|
||||
ifdef VERBOSE
|
||||
Q =
|
||||
else
|
||||
Q = @
|
||||
endif
|
||||
export Q
|
||||
|
||||
# Mandatory compiler flags:
|
||||
|
||||
CFLAGS += -fPIC
|
||||
@ -69,7 +90,7 @@ SILIB = $(LSIDIR)/libsi.a
|
||||
|
||||
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 positioner.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
|
||||
@ -90,14 +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 --cflags libsystemd-daemon)
|
||||
INCLUDES += $(shell $(PKG_CONFIG) --silence-errors --cflags libsystemd-daemon || $(PKG_CONFIG) --cflags libsystemd)
|
||||
DEFINES += -DSDNOTIFY
|
||||
LIBS += $(shell pkg-config --libs libsystemd-daemon)
|
||||
LIBS += $(shell $(PKG_CONFIG) --silence-errors --libs libsystemd-daemon || $(PKG_CONFIG) --libs libsystemd)
|
||||
endif
|
||||
|
||||
LIRC_DEVICE ?= /var/run/lirc/lircd
|
||||
@ -121,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:
|
||||
|
||||
@ -135,7 +157,8 @@ $(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:
|
||||
|
||||
@ -147,7 +170,9 @@ make-libsi: # empty rule makes sure the sub-make for libsi is always called
|
||||
|
||||
.PHONY: vdr.pc
|
||||
vdr.pc:
|
||||
@echo "bindir=$(BINDIR)" > $@
|
||||
@echo "vdrrootdir=$(VDRROOT)" > $@
|
||||
@echo "bindir=$(BINDIR)" >> $@
|
||||
@echo "incdir=$(INCDIR)" >> $@
|
||||
@echo "mandir=$(MANDIR)" >> $@
|
||||
@echo "videodir=$(VIDEODIR)" >> $@
|
||||
@echo "configdir=$(CONFDIR)" >> $@
|
||||
@ -163,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}" >> $@
|
||||
|
||||
@ -177,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)
|
||||
@ -229,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;\
|
||||
@ -250,13 +279,13 @@ plugins: include-dir vdr.pc
|
||||
fi;\
|
||||
if [ -n "$$failed" ] ; then echo; echo "*** failed plugins:$$failed"; echo; exit 1; fi
|
||||
|
||||
clean-plugins:
|
||||
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:
|
||||
|
||||
@ -273,8 +302,13 @@ install-dirs:
|
||||
@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:
|
||||
|
||||
@ -289,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\
|
||||
@ -316,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
|
||||
|
||||
@ -324,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
|
||||
|
160
PLUGINS.html
160
PLUGINS.html
@ -31,14 +31,11 @@ modified {
|
||||
<div class="center">
|
||||
<h1>The VDR Plugin System</h1>
|
||||
|
||||
<b>Version 2.2</b>
|
||||
<b>Version 2.7</b>
|
||||
<p>
|
||||
Copyright © 2015 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 2.2 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,7 +74,6 @@ 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>
|
||||
@ -86,6 +82,7 @@ structures and allows it to hook itself into specific areas to perform special 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>
|
||||
@ -168,7 +165,7 @@ 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
|
||||
@ -187,7 +184,7 @@ 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>
|
||||
@ -1162,11 +1162,59 @@ The returned string may consist of several lines, separated by the newline chara
|
||||
when presenting them to the caller, and the continuation character ('<tt>-</tt>')
|
||||
will be set for all but the last one.
|
||||
<p>
|
||||
<modified>
|
||||
<b>The SVDRP functions are called from the separate "SVDRP server handler" thread.
|
||||
Therefore the plugin needs to take care of proper locking if it accesses any
|
||||
Therefore the plugin needs to take care of proper <a href="#Locking">locking</a> if it accesses any
|
||||
global data.</b>
|
||||
</modified>
|
||||
|
||||
<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>
|
||||
|
||||
@ -1683,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);
|
||||
@ -1998,8 +2046,9 @@ operator!
|
||||
<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>
|
||||
@ -2007,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>
|
||||
|
||||
@ -2023,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
|
||||
|
||||
@ -2031,6 +2094,17 @@ new cMyDeviceHook;
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
and shall not delete this object. It will be automatically deleted when the program ends.
|
||||
<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>
|
||||
|
||||
|
@ -24,3 +24,11 @@ VDR Plugin 'epgtableid0' Revision History
|
||||
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 3.1 2014/01/01 13:29:54 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_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
|
||||
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 3.2 2015/02/17 13:12: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.2.0";
|
||||
static const char *VERSION = "2.4.0";
|
||||
static const char *DESCRIPTION = "EPG handler for events with table id 0x00";
|
||||
|
||||
// --- cTable0Handler --------------------------------------------------------
|
||||
|
@ -94,3 +94,12 @@ VDR Plugin 'hello' Revision History
|
||||
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 3.1 2014/01/01 13:29:54 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_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
|
||||
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 3.2 2015/02/17 13:12:26 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.2.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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 <artlov@gmail.com>, 2004, 2015
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 2.2.0\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,5 +1,5 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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,5 +1,5 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2015 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
|
||||
@ -8,7 +8,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 2.2.0\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"
|
||||
|
@ -79,3 +79,15 @@ VDR Plugin 'osddemo' Revision History
|
||||
- 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 3.1 2014/01/01 13:29:54 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_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
|
||||
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 4.3 2015/04/12 09:35:21 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.3.1";
|
||||
static const char *VERSION = "2.4.1";
|
||||
static const char *DESCRIPTION = "Demo of arbitrary OSD setup";
|
||||
static const char *MAINMENUENTRY = "Osd Demo";
|
||||
|
||||
@ -136,6 +136,91 @@ void DrawImages(cOsd *Osd)
|
||||
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 {
|
||||
@ -590,6 +675,10 @@ eOSState cTrueColorDemo::ProcessKey(eKeys Key)
|
||||
SetArea();
|
||||
DrawImages(osd);
|
||||
break;
|
||||
case k4: Cancel(3);
|
||||
SetArea();
|
||||
DrawEllipseAlignments(osd);
|
||||
return osContinue;
|
||||
case kBack:
|
||||
case kOk: return osEnd;
|
||||
default: return state;
|
||||
|
@ -100,6 +100,23 @@ VDR Plugin 'pictures' Revision History
|
||||
|
||||
- Official release.
|
||||
|
||||
2015-07.23: Version 2.3.1
|
||||
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 3.1 2014/01/01 13:29:54 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_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
|
||||
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
|
||||
|
@ -7,7 +7,7 @@
|
||||
#
|
||||
# See the README file for copyright information and how to reach the author.
|
||||
#
|
||||
# $Id: pic2mpg 3.1 2013/05/23 10:00:23 kls Exp $
|
||||
# $Id: pic2mpg 4.1 2017/10/06 14:42:18 kls Exp $
|
||||
|
||||
use File::Path;
|
||||
use File::Spec;
|
||||
@ -128,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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,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
|
||||
@ -162,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 4.1 2015/07/17 10:14:22 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.3.1";
|
||||
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 3.1 2014/02/08 12:48:12 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;
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2015 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 2.2.0\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) 2015 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 <artlov@gmail.com>, 2015
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-pictures 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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) 2015 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 2.2.0\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"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2015 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 2.2.0\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"
|
||||
|
@ -29,3 +29,11 @@ VDR Plugin 'servicedemo' Revision History
|
||||
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 3.1 2014/01/01 13:29:54 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_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
|
||||
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 3.2 2015/02/17 13:13:05 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.2.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 3.2 2015/02/17 13:13:09 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.2.0";
|
||||
static const char *VERSION = "2.4.0";
|
||||
static const char *DESCRIPTION = "Service demo server";
|
||||
|
||||
class cPluginSvcSvr : public cPlugin {
|
||||
|
@ -130,3 +130,34 @@ VDR Plugin 'skincurses' Revision History
|
||||
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 3.1 2014/01/01 13:29:54 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_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
|
||||
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) 2015 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 2.2.0\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-02-08 11:16+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,6 +19,9 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Eine reine Text-Oberfläche"
|
||||
|
||||
msgid "errors"
|
||||
msgstr "Fehler"
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Stumm"
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2015 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 <artlov@gmail.com>, 2015
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-skincurses 2.2.0\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-02-08 11:16+0100\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"
|
||||
@ -19,6 +19,9 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Tekstipõhine kest"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Hääletu"
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2015 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 2.2.0\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-02-08 11:16+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,6 +19,9 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Tekstipohjainen ulkoasu"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Mykistys"
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2015 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 2.2.0\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-02-08 11:16+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,6 +19,9 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Una interfaccia solo testo"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Muto"
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2015 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 2.2.0\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-02-08 11:16+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,6 +19,9 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Tekstinis apvalkalas"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Išjungti garsą"
|
||||
|
||||
|
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) 2015 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 2.2.0\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-02-08 11:16+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,6 +20,9 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "¿àÞáâÞ âÕÚáâÞÒëÙ ØÝâÕàäÕÙá"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "²ëÚÛ. ÓàÞÜÚÞáâì"
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2015 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 2.2.0\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2015-02-08 11:16+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,6 +19,9 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Iba text vzhµadu"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Stlmi» zvuk"
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: skincurses.c 3.3 2015/02/17 13:13:17 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.2.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();
|
||||
@ -827,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;
|
||||
}
|
||||
|
||||
|
@ -68,3 +68,18 @@ VDR Plugin 'status' Revision History
|
||||
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 3.1 2014/01/01 13:29:54 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_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
|
||||
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 3.2 2015/02/17 13:13:21 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.2.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)
|
||||
|
@ -33,3 +33,11 @@ VDR Plugin 'svdrpdemo' Revision History
|
||||
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 3.1 2014/01/01 13:29:54 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_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
|
||||
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 3.2 2015/02/17 13:13:29 kls Exp $
|
||||
* $Id: svdrpdemo.c 4.1 2018/04/10 13:01:07 kls Exp $
|
||||
*/
|
||||
|
||||
#include <vdr/plugin.h>
|
||||
|
||||
static const char *VERSION = "2.2.0";
|
||||
static const char *VERSION = "2.4.0";
|
||||
static const char *DESCRIPTION = "How to add SVDRP support to a plugin";
|
||||
|
||||
class cPluginSvdrpdemo : public cPlugin {
|
||||
|
4
README
4
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.
|
||||
@ -33,7 +33,7 @@ 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 http://www.tvdr.de/counter.htm. You can also like VDR on facebook
|
||||
at https://www.tvdr.de/counter.htm. You can also like VDR on facebook
|
||||
at https://www.facebook.com/VideoDiskRecorder.
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@ Plugins:
|
||||
- Implemented a universal plugin interface. See the file PLUGINS.html
|
||||
for a detailed description. The man page vdr(1) describes the new options '-L'
|
||||
and '-P' used to load plugins.
|
||||
See http://www.tvdr.de/plugins.htm for a list of available plugins.
|
||||
See https://www.tvdr.de/plugins.htm for a list of available plugins.
|
||||
- Rearranged the remote control key handling to allow plugins to implement
|
||||
additional types of remote controls (see PLUGINS.html, section "Remote Control").
|
||||
The previously used files 'keys.conf' and 'keys-pc.conf' have been replaced
|
||||
|
@ -224,7 +224,7 @@ OSD:
|
||||
- The OSD size is now automatically adjusted to the actual video display
|
||||
(provided the output device implements the GetOsdSize() function).
|
||||
- The OSD now has full TrueColor support. There can be several "pixmaps" that can
|
||||
be overlayed with alpha blending. All existing skins should work out of the box
|
||||
be overlaid with alpha blending. All existing skins should work out of the box
|
||||
with the TrueColor OSD - the only exception being cOsd::GetBitmap(). Since the
|
||||
TrueColor OSD doesn't use bitmaps, this function will return a dummy bitmap, which
|
||||
may not be what the plugin expects. As long as this bitmap is only used for setting
|
||||
|
@ -408,7 +408,7 @@ Misc:
|
||||
- Updated sources.conf to reflect the fact that Astra 4A and SES5 are actually in
|
||||
two separate positions.
|
||||
- Fixed cMarks::GetNextBegin() and cMarks::GetNextEnd(). The behavior of these two
|
||||
functions is now exacly as described in the header file. Editing marks that are
|
||||
functions is now exactly as described in the header file. Editing marks that are
|
||||
placed at exactly the same offset in a recording are now preserved in the cutting
|
||||
process.
|
||||
- The new command line option --chartab can be used to set the default character
|
||||
|
442
UPDATE-2.4.0
Normal file
442
UPDATE-2.4.0
Normal file
@ -0,0 +1,442 @@
|
||||
This is a summary of the changes in VDR 2.4.0 since the last stable
|
||||
version 2.2.0. It only contains things that are of actual importance
|
||||
to the user and doesn't mention the many fixes and improvements that
|
||||
have been made "behind the scenes".
|
||||
|
||||
See the file HISTORY for a detailed list of all changes.
|
||||
|
||||
Peering:
|
||||
|
||||
- If there is more than one VDR in the local network, they can now form a peer-to-peer
|
||||
network, so that timers can be moved freely between them.
|
||||
The following changes have been made to implement this:
|
||||
+ VDR now sends out a broadcast to port 6419/udp, which was assigned to 'svdrp-disc'
|
||||
by the IANA. VDRs listening on that port will automatically initiate an SVDRP
|
||||
connection to the broadcasting VDR, and in turn send out a broadcast to make
|
||||
other VDRs connect to them. That way all VDRs within the local network will
|
||||
have permanent "peer-to-peer" SVDRP connections between each other. The
|
||||
configuration in the svdrphosts.conf file is taken into account when considering
|
||||
whether or not to respond to an SVDRP discover broadcast.
|
||||
+ The new SVDRP command PING is used by automatically established peer-to-peer
|
||||
connections to keep them alive.
|
||||
+ The new function GetSVDRPServerNames() can be used to get a list of all VDRs
|
||||
this VDR is connected to via SVDRP.
|
||||
+ The new function ExecSVDRPCommand() can be used to execute an SVDRP command on
|
||||
one of the servers this VDR is connected to, and retrieve the result.
|
||||
The helper functions SVDRPCode() and SVDRPValue() can be used to easily access
|
||||
the codes and values returned by ExecSVDRPCommand().
|
||||
+ The new SVDRP command POLL is used by automatically established peer-to-peer
|
||||
connections to trigger fetching remote timers.
|
||||
+ The new options "Setup/Miscellaneous/SVDRP peering", ".../SVDRP host name" and
|
||||
".../SVDRP default host" can be used to configure automatic peering between VDRs
|
||||
in the same network. Peering is disabled by default and can be enabled by setting
|
||||
"SVDRP peering" to "yes".
|
||||
+ The "Edit timer" menu now has a new parameter "Record on", which can be used to
|
||||
select the VDR on which this timer shall record. Timers can be freely moved
|
||||
between connected VDRs by simply selecting the desired machine in this field.
|
||||
+ The cTimer class now has a new member named 'remote', which holds the name of the
|
||||
remote server this timer will record on. If this is NULL, it is a local timer.
|
||||
+ Added a note to the "Pausing live video" section of the MANUAL, stating that
|
||||
the timer for paused live video will always record on the local VDR, even if
|
||||
an "SVDRP default host" has been set for normal timer recordings.
|
||||
+ The Perl script 'peerdemo' shows how one can find all the VDRs in the local network
|
||||
using the peer connection mechanism.
|
||||
|
||||
Conditional Access:
|
||||
|
||||
- Implemented support for MTD ("Multi Transponder Decryption"). This allows a CAM
|
||||
that is capable of decrypting more than one channel ("Multi Channel Decryption")
|
||||
to decrypt channels from different transponders. See the remarks in mtd.h on
|
||||
what a derived cCamSlot class needs to do in order to activate MTD.
|
||||
- The Setup/CAM menu now displays which device an individual CAM is currently
|
||||
assigned to.
|
||||
- The channel/CAM relations (i.e. the information which CAM can decrypt a given
|
||||
channel) are now stored in the file 'cam.data' in the cache directory.
|
||||
This speeds up switching to encrypted channels after newly starting VDR, in case
|
||||
there is more than one CAM in the system.
|
||||
The file 'cam.data' is not written if it is read-only.
|
||||
- The mechanism of trying different CAMs when switching to an encrypted channel is
|
||||
now only triggered if there actually is more than one CAM in the system.
|
||||
- CAMs that can handle multiple devices at the same time can now indicate this
|
||||
by creating the first cCamSlot as usual, and every other cCamSlot by giving
|
||||
it the first one as its "MasterSlot". To VDR this means that when searching
|
||||
for a CAM that can decrypt a particular channel, it only needs to ask the
|
||||
master CAM slot whether it is suitable for decrypting, and can skip all the
|
||||
other slots belonging to the same master. This can greatly speed up channel
|
||||
switching on systems with more than one CAM (that can handle multiple devices).
|
||||
- The LCARS skin now displays the master CAM's number when a device is tuned to
|
||||
an encrypted channel.
|
||||
- The Setup/CAM menu now only displays master CAMs.
|
||||
- Detecting whether a particular CAM actually decrypts a given channel is now
|
||||
done separately for each receiver.
|
||||
- The function cCamSlot::Decrypt() can now also be called with Data == NULL.
|
||||
This is necessary to allow CAMs that copy the incoming data into a separate buffer
|
||||
to return previously received and decrypted TS packets. See ci.h for details.
|
||||
Plugins that implement a derived cCamSlot need to properly handle this case, and
|
||||
plugins that implement a derived cDevice need to call Decrypt() in their
|
||||
GetTSPacket() function even if the incoming buffer is currently empty (see
|
||||
cDvbDevice::GetTSPacket()).
|
||||
- CAMs are now sent a generated EIT packet that contains a single 'present event' for
|
||||
the current SID, in order to avoid any parental rating dialogs.
|
||||
- When selecting a device/CAM combination for live viewing, CAMs that are known to
|
||||
decrypt the requested channel are now given a higher priority than preferring the
|
||||
primary device.
|
||||
- Extended the CI API to allow plugins to implement additional CAM resources.
|
||||
- The new configuration file 'camresponses.conf' can be used to define automatic
|
||||
responses to CAM menus, for instance to avoid annyoing popup messages or entering
|
||||
the parental rating PIN. See vdr.5 for details.
|
||||
|
||||
Timers:
|
||||
|
||||
- The cTimer class now has a new member named 'remote', which holds the name of the
|
||||
remote server this timer will record on. If this is NULL, it is a local timer.
|
||||
- Timers from other VDRs that are connected to this VDR via SVDRP are now
|
||||
automatically fetched and stored in the global Timers list. In order for this
|
||||
to work, all of the channels used by timers on the remote VDR must also be
|
||||
defined on the local VDR (however, not necessarily in the same sequence).
|
||||
- Accessing the global Timers list now has to be protected by proper locking,
|
||||
because SVDRP commands are now executed in a separate thread.
|
||||
The introduction of this locking mechanism required the following changes:
|
||||
+ The new classes cStateLock and cStateKey are used to implement locking
|
||||
with quick detection of state changes.
|
||||
+ cConfig::cConfig() now has a parameter that indicates whether this list
|
||||
requires locking.
|
||||
+ The global lists of Timers, Channels, Schedules and Recordings are no longer
|
||||
static variables. They are now pointers that need to be retrieved through
|
||||
a call to cTimers::GetTimersRead/Write(), cChannels::GetChannelsRead/Write(),
|
||||
cSchedules::GetSchedulesRead/Write() and cRecordings::GetRecordingsRead/Write(),
|
||||
respectively.
|
||||
+ References from/to link channels are now removed in cChannels::Del() rather
|
||||
than cChannel::~cChannel(), to make sure the caller holds a proper lock.
|
||||
+ cChannel::HasTimer() has been removed. This information is now retrieved
|
||||
via cSchedule::HasTimer().
|
||||
+ Several member functions of cChannel, cTimer, cMarks and cRecording have
|
||||
been made 'const', and some of them are now available as both 'const' and
|
||||
'non-const' versions.
|
||||
+ The cChannel::Set...() functions are now 'bool' and return true if they have
|
||||
actually changed any of the channels's members.
|
||||
+ cChannels::SetModified() has been renamed to cChannels::SetModifiedByUser().
|
||||
+ cChannels::Modified() has been renamed to cChannels::ModifiedByUser(), and
|
||||
now has a 'State' parameter that allows the caller to see whether a channel
|
||||
has been modified since the last call to this function with the same State
|
||||
variable.
|
||||
+ The macros CHANNELSMOD_NONE/_AUTO/_USER have been removed.
|
||||
+ cMarks now requires locking via cStateKey.
|
||||
+ cSortedTimers now requires a pointer to the list of timers.
|
||||
+ cEvent::HasTimer() no longer scans the list of timers to check whether an event
|
||||
is referenced by a timer, but rather keeps score of how many timers reference
|
||||
it. This was necessary in order to avoid having to lock the list of timers from
|
||||
within a cEvent.
|
||||
+ The new class cListGarbageCollector is used to temporary store any objects deleted
|
||||
from cLists that require locking. This allows pointers to such objects to be
|
||||
dereferenced even if the objects are no longer part of the list.
|
||||
+ cListBase::Contains() can be used to check whether a particular object is still
|
||||
contained in that list.
|
||||
+ Outdated events are no longer "phased out", but rather deleted right away and thus
|
||||
taken care of by the new "garbage collector" of the list.
|
||||
+ Deleted cRecording objects are no longer kept in a list of "vanished" recordings,
|
||||
but are rather taken care of by the new "garbage collector" of the list.
|
||||
+ cSchedules::ClearAll() has been removed. The functionality is now implemented
|
||||
directly in cSVDRPServer::CmdCLRE().
|
||||
+ cSchedule now has a member Modified(), which can be used with a State variable
|
||||
to quickly determine whether this schedule has been modified since the last call
|
||||
to this function with the same State variable.
|
||||
+ cSchedulesLock has been removed. Locking the list of schedules is now done via
|
||||
the cList's new locking mechanism.
|
||||
+ The 'OnlyRunningStatus' parameters in cEpgHandler::BeginSegmentTransfer() and
|
||||
cEpgHandler::EndSegmentTransfer() are now obsolete. They are still present in
|
||||
the interface for backward compatibility, but may be removed in a future version.
|
||||
Their value is always 'false'.
|
||||
+ The constant tcMod is no longer used in cStatus::TimerChange(). The definition is
|
||||
still there for backward compatibility.
|
||||
- Plugins that access the global lists of Timers, Channels, Recordings or Schedules
|
||||
will need to be adapted as follows:
|
||||
+ Instead of directly accessing the global variables Timers, Channels or Recordings,
|
||||
they need to set up a cStateKey variable and call the proper getter function,
|
||||
as in
|
||||
cStateKey StateKey;
|
||||
if (const cTimers *Timers = cTimers::GetTimersRead(StateKey)) {
|
||||
// access the timers
|
||||
StateKey.Remove();
|
||||
}
|
||||
and
|
||||
cStateKey StateKey;
|
||||
if (cTimers *Timers = cTimers::GetTimersWrite(StateKey)) {
|
||||
// access the timers
|
||||
StateKey.Remove();
|
||||
}
|
||||
See timers.h, thread.h and tools.h for details on this new locking mechanism.
|
||||
+ There are convenience macros for easily accessing these lists without having
|
||||
to explicitly set up a cStateKey and calling its Remove() function. These macros
|
||||
have the form LOCK_*_READ/WRITE (with '*' being TIMERS, CHANNELS, SCHEDULES or
|
||||
RECORDINGS). Simply put such a macro before the point where you need to access
|
||||
the respective list, and there will be a pointer named Timers, Channels, Schedules
|
||||
or Recordings, respectively, which is valid until the end of the current block.
|
||||
+ If a plugin needs to access several of the global lists in parallel, locking must
|
||||
always be done in the sequence Timers, Channels, Recordings, Schedules. This is
|
||||
necessary to make sure that different threads that need to lock several lists at
|
||||
the same time don't end up in a deadlock.
|
||||
+ Some pointer variables may need to be made 'const'. The compiler will tell you
|
||||
about these.
|
||||
- If a timer is newly created with the Red button in the Schedule menu, and the timer
|
||||
is presented to the user in the "Edit timer" menu because it will start immediately,
|
||||
it now *must* be confirmed with "Ok" to set the timer. Otherwise the timer will not
|
||||
be created.
|
||||
- The function cTimer::ToText() no longer returns a newline character at the end of
|
||||
the string. The newline is now added by the caller as necessary. This was changed
|
||||
because cTimer::ToText() is now also needed in a context where the terminating
|
||||
newline can't be used. Consequently, cChannel::ToText() and cMark::ToText() have
|
||||
been modified accordingly.
|
||||
- Timers now have unique ids instead of numbers, which remain valid as long as this
|
||||
instance of VDR is running. This means that timers are no longer continuously
|
||||
numbered from 1 to N in LSTT. There may be
|
||||
gaps in the sequence, in case timers have been deleted.
|
||||
- Timers are now linked to EPG events even if they are inactive. By default Events that
|
||||
are linked to inactive timers are marked with 'I' and 'i', depending on whether the
|
||||
timer would record the entire Event or only part of it.
|
||||
The function cSkinDisplayMenu::SetItemEvent() now has an additional parameter named
|
||||
TimerActive, which indicates whether the timer that would record this event (if any)
|
||||
is active. A plugin may react on this when displaying a menu line for an event.
|
||||
The old version of cSkinDisplayMenu::SetItemEvent() (without the TimerActive
|
||||
parameter) is still there for backwards compatibility. It may be removed in a future
|
||||
version, so plugin authors should switch to the new one.
|
||||
- Improved handling VPS timers to better react to EPG changes during an ongoing recording.
|
||||
|
||||
Plugins:
|
||||
|
||||
- The dvbhddevice plugin is no longer part of the VDR source archive.
|
||||
You can get the latest version of this plugin from the author's repository at
|
||||
https://bitbucket.org/powARman/dvbhddevice.
|
||||
- The dvbsddevice and rcu plugins are no longer part of the VDR source archive.
|
||||
You can get the latest versions of these plugins from ftp://ftp.tvdr.de/vdr/Plugins.
|
||||
- The -V and -h options now list the plugins in alphabetical order.
|
||||
- Added some guidelines and recommendations to the 'Logging' section of PLUGINS.html.
|
||||
The most important being: implement a command line option to control the level
|
||||
of logging (in particular allow turning off logging completely!) and never print
|
||||
anything to stdout or stderr (unless one of the listed exceptions applies).
|
||||
- Added a note to PLUGINS.html about writing log messages in English.
|
||||
- The new function cStatus::MarksModified() can be implemented by plugins to get
|
||||
informed about any modifications to the editing marks of the currently played
|
||||
recording.
|
||||
|
||||
Skins:
|
||||
|
||||
- The main menu of the LCARS skin now displays a small rectangle on the left side
|
||||
of a timer if this is a remote timer. The color of that rectangle changes if
|
||||
the timer is currently recording on the remote VDR.
|
||||
- Skins can now implement cSkinDisplayMenu::MenuOrientation() to display horizontal
|
||||
menus.
|
||||
- The LCARS skin now displays the master CAM's number when a device is tuned to
|
||||
an encrypted channel.
|
||||
|
||||
Remote control:
|
||||
|
||||
- The new setup option "Recording/Record key handling" can be used to define
|
||||
what happens if the Record key on the remote control is pressed during
|
||||
live tv.
|
||||
- If the Channel+/- keys are pressed while in the Schedules menu, the menu is now
|
||||
switched to the EPG of the new current channel.
|
||||
|
||||
Devices:
|
||||
|
||||
- The command line option -D now accepts the value '-' (as in -D-), which prevents
|
||||
VDR from using any DVB devices.
|
||||
- The function cDevice::SetCurrentChannel(const cChannel *Channel) is now deprecated
|
||||
and may be removed in a future version. Use SetCurrentChannel(int ChannelNumber)
|
||||
instead.
|
||||
- Signal strength and quality (CNR) are now determined via DVB API 5 (if available).
|
||||
Fallback is the old DVB API 3 method.
|
||||
- The new function cDevice::SignalStats() (if implemented by an actual device) returns
|
||||
statistics about the currently received signal.
|
||||
- The function cDevice::GetVideoSystem() (which has been deprecated since version 2.1.6)
|
||||
has been finally removed.
|
||||
- Switching the primary device is no longer done via osSwitchDvb (which has been
|
||||
removed), but rather by the main program loop reacting to changes in Setup.PrimaryDVB.
|
||||
|
||||
EPG:
|
||||
|
||||
- The character 0x0D is now stripped from EPG texts.
|
||||
- The EPG scanner no longer moves the dish if there is a positioner.
|
||||
- The function cEpgHandlers::BeginSegmentTransfer() is now boolean.
|
||||
See the description in epg.h for the meaning of the return value.
|
||||
- The cEvent class now has a new member 'aux', in which external applications can
|
||||
store auxiliary information with an event. This string has no meaning whatsoever to
|
||||
VDR itself, and it will not be written into the info file of a recording that is
|
||||
made for such an event.
|
||||
- Changed the default return value of cEpgHandler::BeginSegmentTransfer() to true, to
|
||||
avoid problems with derived classes that don't implement this function.
|
||||
- The EIT filter no longer parses data from "other TS", to avoid problems with
|
||||
broadcasters who transmit faulty EIT data.
|
||||
|
||||
OSD:
|
||||
|
||||
- The new function cOsd::MaxPixmapSize() can be called to determine the maximum size
|
||||
a cPixmap may have on the current OSD. The 'osddemo' example has been modified
|
||||
accordingly. Plugin authors may want to use this function in case they use pixmaps
|
||||
that are larger than the full OSD size. The default implementation sets this limit
|
||||
to 2048x2048 pixel.
|
||||
- Added some comment to cPixmap about the relation between OSD, ViewPort and DrawPort.
|
||||
- The new setup option "OSD/Default sort mode for recordings" can be used to define
|
||||
how recordings shall be sorted by default (either by time or by name, with "by time"
|
||||
being the default). If a particular sort mode has been selected for a folder by
|
||||
pressing '0', the default no longer applies to that folder. Repeating timers no
|
||||
longer write a ".sort" file into a recordings folder to have the recordings sorted
|
||||
by time.
|
||||
- The function cOsd::GetBitmap() is now 'protected'. If a plugin doesn't compile with
|
||||
this version of VDR, you can uncomment the line
|
||||
//#define DEPRECATED_GETBITMAP
|
||||
in osd.h as a quick workaround. In the long run the plugin will need to be adapted.
|
||||
- Background modifications of channels, timers and events are now displayed immediately
|
||||
in the corresponding menus.
|
||||
- The Timers menu now displays the name of the remote VDR in front of the timer's
|
||||
file name, if this is a remote timer.
|
||||
- The width and height of the OSD are now limited to the actual maximum dimensions
|
||||
of the output device, taking into account the top and left offset.
|
||||
- Added a note to the description of cFont::Size(), regarding possible differences
|
||||
between it and cFont::Height().
|
||||
- Added cFont::Width(void) to get the default character width and allow stretched
|
||||
font drawing in high level OSDs.
|
||||
- cOsdMenu::Display() now checks whether the OSD size has changed and if so calls
|
||||
SetDisplayMenu().
|
||||
- The option "Setup/Miscellaneous/Show channel names with source" can now be set to
|
||||
"type" or "full" to show either the type or the full name of the source.
|
||||
- The "Channels" menu now indicates whether a channel is encrypted ('X') or a radio
|
||||
channel ('R').
|
||||
- The timeout for the channel display is now reset whenever the channel or EPG data
|
||||
changes.
|
||||
- OSD menus now try to keep the offset of the list cursor at a constant position on
|
||||
the screen, even if the list is modified while being displayed.
|
||||
- If an event in the Schedules menu is marked with a 'T' or 'I' and the user presses the
|
||||
Red button to edit the timer, local timers are now preferred over remote timers
|
||||
in case there is more than one timer that will record that event.
|
||||
- The new setup option "OSD/Sorting direction for recordings" can be used to switch
|
||||
the sequence in which recordings are presented in the "Recordings" menu between
|
||||
ascending (oldest first) and descendeng (newest first).
|
||||
- When selecting a folder for a recording or timer, it is now possible to open a folder
|
||||
even if it doesn't contain any subfolders.
|
||||
|
||||
Recordings:
|
||||
|
||||
- Recordings now have unique ids instead of numbers, which remain valid as long as
|
||||
this instance of VDR is running. This means that recordings are no longer continuously
|
||||
numbered from 1 to N in LSTR. There may be gaps in the sequence, in case recordings
|
||||
have been deleted, and they are not necessarily listed in numeric order.
|
||||
- Added detection of 24fps.
|
||||
- The script that gets called for recordings is now also called right before a
|
||||
recording is edited, with the first parameter being "editing".
|
||||
- Implemented a frame parser for H.265 (HEVC) recordings.
|
||||
- When moving recordings between volumes, the "Recordings" menu now displays those items
|
||||
that have not yet been moved completely as non-selectable. This avoids situations
|
||||
where trying to play such a recording might fail.
|
||||
- When moving a recording to a different folder, the cursor is no longer placed on the
|
||||
new location of the recording, but rather stays in the original folder.
|
||||
If the original folder got empty by moving away the last recording
|
||||
it contained, the cursor is moved up until a non empty folder is found.
|
||||
|
||||
SVDRP:
|
||||
|
||||
- The SVDRP port now accepts multiple concurrent connections. You can now keep an
|
||||
SVDRP connection open as long as you wish, without preventing others from
|
||||
connecting. Note, though, that SVDRP connections still get closed automatically
|
||||
if there has been no activity for 300 seconds (configurable via
|
||||
"Setup/Miscellaneous/SVDRP timeout (s)").
|
||||
- The SVDRP log messages have been unified and now always contain the IP and port
|
||||
number of the remote host.
|
||||
- SVDRP connections are now handled in a separate "SVDRP server handler" thread,
|
||||
which makes them more responsive. Note that there is only one thread that handles
|
||||
all concurrent SVDRP connections. That way each SVDRP command is guaranteed to be
|
||||
processed separately, without interfering with any other SVDRP commands that might
|
||||
be issued at the same time. Plugins that implement SVDRP commands may need to take
|
||||
care of proper locking if the commands access global data.
|
||||
- You can now set DumpSVDRPDataTransfer in svdrp.c to true to have all SVDRP
|
||||
communication printed to the console for debugging.
|
||||
- The SVDRP commands that deal with timers (DELT, LSTT, MODT, NEWT, NEXT and UPDT)
|
||||
as well as any log messages that refer to timers, now use a unique id for each
|
||||
timer, which remains valid as long as this instance of VDR is running. This means
|
||||
that timers are no longer continuously numbered from 1 to N in LSTT. There may be
|
||||
gaps in the sequence, in case timers have been deleted.
|
||||
- All timer related response strings from SVDRP commands now use the channel ID
|
||||
instead of channel numbers.
|
||||
- The SVDRP command DELT no longer checks whether the timer that shall be deleted
|
||||
is currently recording.
|
||||
- The SVDRP command DELC now refuses to delete the very last channel in the list,
|
||||
to avoid ending up with an empty channel list.
|
||||
- The SVDRP commands that deal with recordings (DELR, EDIT, LSTR, MOVR, and PLAY)
|
||||
now use a unique id for each recording, which remains valid as long as this
|
||||
instance of VDR is running. This means that recordings are no longer continuously
|
||||
numbered from 1 to N in LSTR. There may be gaps in the sequence, in case recordings
|
||||
have been deleted, and they are not necessarily listed in numeric order.
|
||||
- Changed 'number' to 'id' in the help texts of SVDRP commands that deal with
|
||||
timers.
|
||||
- The SVDRP command LSTC can now list the channels with channel ids if the option
|
||||
':ids' is given.
|
||||
- If 0 is given as the channel number in the SVDRP command LSTC, the data of the
|
||||
current channel is listed.
|
||||
- The new SVDRP commands 'LSTD' and 'PRIM' can be used to list all available devices
|
||||
and to switch the primary device.
|
||||
|
||||
Misc:
|
||||
|
||||
- Added a section about Output Devices to the INSTALL file.
|
||||
- The -u option now also accepts a numerical user id.
|
||||
- The cRwLock class now allows nested read locks within a write lock from the
|
||||
same thread. This fixes possible crashes when moving or deleting channels in
|
||||
the menu or through SVDRP (as well as other operations that try to acquire a
|
||||
read lock within a write lock).
|
||||
- Added support for the systemd watchdog.
|
||||
- PIDs can now be added to and deleted from a cReceiver while it is attached to
|
||||
a cDevice, without having to detach it first and re-attach it afterwards.
|
||||
- Log messages about switching channels now include the channel ID.
|
||||
- The constructor of cHash (via cHashBase) now has an additional parameter (OwnObjects)
|
||||
which, if set to true, makes the hash take ownership of the hashed objects, so that
|
||||
they are deleted when the hash is cleared or destroyed.
|
||||
- cListObject now implements a private copy constructor and assignment operator, to keep
|
||||
derived objects from calling them implicitly.
|
||||
- The Makefiles have been modified so that during the build process they no longer
|
||||
display the actual (lengthy) commands, but rather just the name of the file that
|
||||
is being built, as in
|
||||
CC vdr.o
|
||||
The first two characters indicate the kind of operation (CC=compile, LD=link,
|
||||
AR=archive, MO=msgfmt, GT=xgettext, PO=msgmerge, IN=install).
|
||||
This way it is much easier to spot error messages and warnings, since they are not
|
||||
buried under tons of text.
|
||||
Add VERBOSE=1 to the 'make' call in the VDR source directory to see the
|
||||
actual commands that are executed.
|
||||
Plugin authors should modify their makefiles accordingly, by simply preceding
|
||||
the respective commands with '$(Q)' and inserting '@echo XX $@' (where XX is one
|
||||
of the character combinations listed above) before the command.
|
||||
The newplugin script has also been modified accordingly.
|
||||
Note that if you build a plugin directly in the plugin's own source directory,
|
||||
the $(Q) macro won't be defined and commands will be displayed. You can add
|
||||
Q=@ to the make call to have it less verbose (provided the plugin's Makefile
|
||||
was modified as described above).
|
||||
- Added backtrace functions for debugging (see cBackTrace in thread.h).
|
||||
- Added checking the correct sequence of locking global lists.
|
||||
At the first occurrence of an invalid locking
|
||||
sequence, the 20 most recent locks will be written to the log file, followed by a
|
||||
backtrace that led to the call in question. This code can be activated by defining
|
||||
the macro DEBUG_LOCKSEQ in thread.c (which is on by default).
|
||||
When debugging an actual invalid locking sequence, you can additionally define
|
||||
the macro DEBUG_LOCKCALL in thread.c, which will add information about the caller
|
||||
of each lock. Note that this may cause some stress on the CPU, therefore it is off
|
||||
by default.
|
||||
- The file Make.config.template now reacts on DEBUG=1 in the 'make' command line,
|
||||
and disables code optimizations by setting -O0.
|
||||
This can be helpful when backtracing highly optimized code. You may want to
|
||||
'make distclean' before running 'make' with a modified setting of DEBUG, to make
|
||||
sure all object files are newly compiled.
|
||||
- Introduced the new macro DISABLE_TEMPLATES_COLLIDING_WITH_STL, which can be defined
|
||||
before including tools.h in case some plugin needs to use the STL and gets error
|
||||
messages regarding one of the template functions defined in tools.h.
|
||||
- The macros used to control deprecated code or functions have been changed to hold
|
||||
numeric values (0 and 1), so that they can be controlled at compile time, without
|
||||
having to edit the actual source code.
|
||||
- The default for DEPRECATED_VDR_CHARSET_OVERRIDE has been set to 0, which means VDR
|
||||
no longer reacts on the environment variable VDR_CHARSET_OVERRIDE. You can add
|
||||
'DEPRECATED_VDR_CHARSET_OVERRIDE=1' when compiling in order to restore this
|
||||
functionality. However, it is recommended to use the command line option --chartab
|
||||
instead.
|
||||
- Disabled the use of posix_fadvise() when reading (i.e. replaying), since it caused
|
||||
stuttering replay in fast forward and fast rewind mode in case the video directory
|
||||
is mounted via NFS. You can re-enable it by setting the macro USE_FADVISE_READ to 1
|
||||
in tools.c.
|
119
UPDATE-2.6.0
Normal file
119
UPDATE-2.6.0
Normal file
@ -0,0 +1,119 @@
|
||||
This is a summary of the changes in VDR 2.6.0 since the last stable
|
||||
version 2.4.0. It only contains things that are of actual importance
|
||||
to the user and doesn't mention the many fixes and improvements that
|
||||
have been made "behind the scenes".
|
||||
|
||||
See the file HISTORY for a detailed list of all changes.
|
||||
|
||||
Timers:
|
||||
|
||||
- Implemented "Pattern Timers" (see MANUAL, vdr.1 and vdr.5 for details).
|
||||
- The margins for timer recordings are now always limited to the duration of the
|
||||
previous and next event.
|
||||
- Spawned timers that don't use VPS now automatically adjust their start/stop times
|
||||
to changes in the respective event's times.
|
||||
|
||||
EPG:
|
||||
|
||||
- Events in the past are no longer marked as having a timer in the Schedules
|
||||
menu.
|
||||
- Improved handling EPG data from the EIT tables:
|
||||
+ Table 0x4F is now completely ignored.
|
||||
+ Once a schedule has seen events from 0x5X, tables 0x6X are ignored for that
|
||||
schedule.
|
||||
+ When looking up an event in its schedule, the start time is used for tables 0x6X, and the
|
||||
event id for tables 0x4E and 0x5X.
|
||||
+ When hashing events by event id or start time, existing older entries in the hash
|
||||
tables are now deleted before entering the new ones.
|
||||
+ The function cSchedule::GetEvent() is now deprecated and may be removed in a future
|
||||
version. Use GetEventById() and GetEventByTime() instead.
|
||||
+ On channels that use proper event ids a change of the start time no longer
|
||||
causes a new event to be created, but rather modifies the existing one. This
|
||||
avoids possible interruptions in VPS recordings in case the event's start time
|
||||
is changed while the recording is already going on.
|
||||
- Fixed the timer indicator in the Schedule menu in case an event is already over, but the
|
||||
timer is still recording.
|
||||
- Fixed unlocking vs. call to EpgHandlers.EndSegmentTransfer().
|
||||
|
||||
Devices:
|
||||
|
||||
- Increased the number of possible modulation systems in cDevice::GetDevice().
|
||||
- Improved cSectionSyncer to make sure that no sections are missed, and to allow
|
||||
handling partially used segments (as in the EIT) and processing sections in random
|
||||
order. Segment syncing is now done with the two member functions Check() and
|
||||
Processed(). The old functions Sync() and Repeat() are deprecated and may be
|
||||
removed in a future version. See the comments in filter.h for a description on
|
||||
how to use these new function.
|
||||
- Added a device hook for detecting whether a device provides EIT data.
|
||||
|
||||
Recordings:
|
||||
|
||||
- Made the functions cRecordingInfo::SetData() and cRecordingInfo::SetAux() public.
|
||||
- Fixed setting the 'title' of a recording's info to the recording's name if there
|
||||
is no info file (the change in version 1.7.28 broke the fallback to the old 'summary.vdr').
|
||||
- Added some missing user command calls for copying, renaming and moving recordings.
|
||||
- Recordings are now checked for errors:
|
||||
+ On TS level, the continuity counter, transport error indicator and scramble flags are
|
||||
checked.
|
||||
+ On frame level it is checked whether there are no gaps in the PTS.
|
||||
+ The number of errors during a recording is stored in the recording's 'info' file, with
|
||||
the new tag 'O'.
|
||||
+ Spawned timers that shall avoid recording reruns only store the recording's name in
|
||||
the donerecs,data file if there were no errors during recording, and if the timer has
|
||||
actually finished.
|
||||
- The Recordings menu now marks recordings with errors with an exclamation mark ('!'),
|
||||
and the number of errors (if any) is displayed in the recording's Info menu.
|
||||
|
||||
Replay:
|
||||
|
||||
- Fixed scaling subtitles with anti-aliasing.
|
||||
|
||||
Conditional Access:
|
||||
|
||||
- Decreased the scrambling timeout for CAMs known to decrypt a certain channel, so
|
||||
that it won't collide with MAXBROKENTIMEOUT in recorder.c.
|
||||
|
||||
Skins:
|
||||
|
||||
- The new functions cTimer::Start/StopTimeEvent() are now used in the LCARS skin to display
|
||||
the start/stop times of timers in the main menu.
|
||||
|
||||
SVDRP:
|
||||
|
||||
- The SVDRP command DELC now also accepts a channel id.
|
||||
|
||||
Misc:
|
||||
|
||||
- Added support for HEVC-video and AC-4-audio.
|
||||
- EXPIRELATENCY now only applies to VPS timers.
|
||||
- Removed the macros __STL_CONFIG_H, _STL_ALGOBASE_H and _MOVE_H from tools.h. If your
|
||||
plugin insists in using "using namespace std;" you can still define
|
||||
DISABLE_TEMPLATES_COLLIDING_WITH_STL before including any VDR header files.
|
||||
- The cFile class has been partially deprecated:
|
||||
+ The handling of file handles was not thread-safe.
|
||||
+ It was only actually used in svdrp.c.
|
||||
+ cFile::Ready() now processes only its own file descriptor by calling FileReady()
|
||||
instead of AnyFileReady().
|
||||
- The transponder value of channels is now cached, because cChannel::Transponder(void)
|
||||
is called very often.
|
||||
- Added code for the 'qad' audio track.
|
||||
- The 'Edit path' dialog now also shows the total size of all recordings in that path.
|
||||
- The macro DEPRECATED_VDR_CHARSET_OVERRIDE and the related code has been removed.
|
||||
- The default for DEPRECATED_SETCURRENTCHANNEL has been set to 0, which means that
|
||||
the function SetCurrentChannel(const cChannel *Channel) is no longer available.
|
||||
You can add 'DEPRECATED_SETCURRENTCHANNEL=1' when compiling in order to restore this
|
||||
functionality. However, it is recommended to use SetCurrentChannel(int ChannelNumber)
|
||||
instead.
|
||||
- The macro DEPRECATED_GETBITMAP and the related code has been removed.
|
||||
- The default for DEPRECATED_SKIN_SETITEMEVENT has been set to 0, which means that
|
||||
the function cSkinDisplayMenu::SetItemEvent() without the TimerActive parameter is
|
||||
no longer available. You can add 'DEPRECATED_SKIN_SETITEMEVENT=1' when compiling in
|
||||
order to restore this functionality. However, it is recommended to use the function
|
||||
with the TimerActive parameter instead.
|
||||
- Now using __cplusplus instead of DISABLE_TEMPLATES_COLLIDING_WITH_STL, and using
|
||||
std::min(), std::max() and std::swap() if available.
|
||||
- No longer permanently looping through PMT PIDs, which caused problems with some
|
||||
SatIP receivers.
|
||||
- Replaced all umlauts in the example channels.conf with their ae, oe, ue substitutes
|
||||
to avoid problems on UTF-8 systems.
|
||||
- Added missing '0x09=H.265 video, 0x19 = AC4 audio' to vdr.5.
|
29
camresponses.conf
Normal file
29
camresponses.conf
Normal file
@ -0,0 +1,29 @@
|
||||
# CAM responses for VDR
|
||||
#
|
||||
# Format:
|
||||
#
|
||||
# nr text action
|
||||
#
|
||||
# nr: the number of the CAM this action applies to (0 = all CAMs)
|
||||
# text: the text in the CAM menu to react on (must be quoted with '"' if it contains
|
||||
# blanks, escape '"' with '\')
|
||||
# action: the action to take if the given text is encountered
|
||||
#
|
||||
# Possible actions are:
|
||||
#
|
||||
# - DISCARD: simply discard the menu (equivalent to pressing 'Back' on the RC)
|
||||
# - CONFIRM: confirm the menu (equivalent to pressing 'OK' without selecting a
|
||||
# particular item)
|
||||
# - SELECT: select the menu item containing the text (equivalent to positioning
|
||||
# the cursor on the item and pressing 'OK')
|
||||
# - <number>: the given number is sent to the CAM as if it were typed in by the user
|
||||
# (provided this is an input field).
|
||||
#
|
||||
# Note that the text given in a rule must match exactly, including any leading or
|
||||
# trailing blanks. If in doubt, you can get the exact text from the log file.
|
||||
# Action keywords are case insensitive.
|
||||
#
|
||||
# Examples:
|
||||
|
||||
# * "Hello! This is your annoying \"nag\" message!" DISCARD
|
||||
# 3 "Please enter your PIN" 1234
|
94
channels.c
94
channels.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: channels.c 4.3 2015/09/09 10:21:22 kls Exp $
|
||||
* $Id: channels.c 5.3 2024/03/02 16:21:16 kls Exp $
|
||||
*/
|
||||
|
||||
#include "channels.h"
|
||||
@ -97,18 +97,32 @@ cChannel& cChannel::operator= (const cChannel &Channel)
|
||||
provider = strcpyrealloc(provider, Channel.provider);
|
||||
portalName = strcpyrealloc(portalName, Channel.portalName);
|
||||
memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__);
|
||||
nameSource = NULL; // these will be recalculated automatically
|
||||
shortNameSource = NULL;
|
||||
UpdateNameSource();
|
||||
parameters = Channel.parameters;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void cChannel::UpdateNameSource(void)
|
||||
{
|
||||
if (Setup.ShowChannelNamesWithSource == 0) {
|
||||
nameSource = NULL;
|
||||
shortNameSource = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Setup.ShowChannelNamesWithSource == 1)
|
||||
nameSource = cString::sprintf("%s (%c)", name, cSource::ToChar(source));
|
||||
else
|
||||
nameSource = cString::sprintf("%s (%s)", name, *cSource::ToString(source));
|
||||
|
||||
shortNameSource = cString::sprintf("%s (%c)", shortName, cSource::ToChar(source));
|
||||
}
|
||||
|
||||
const char *cChannel::Name(void) const
|
||||
{
|
||||
if (Setup.ShowChannelNamesWithSource && !groupSep) {
|
||||
if (isempty(nameSource))
|
||||
nameSource = cString::sprintf("%s (%c)", name, cSource::ToChar(source));
|
||||
return nameSource;
|
||||
if (!isempty(nameSource))
|
||||
return nameSource;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
@ -118,9 +132,8 @@ const char *cChannel::ShortName(bool OrName) const
|
||||
if (OrName && isempty(shortName))
|
||||
return Name();
|
||||
if (Setup.ShowChannelNamesWithSource && !groupSep) {
|
||||
if (isempty(shortNameSource))
|
||||
shortNameSource = cString::sprintf("%s (%c)", shortName, cSource::ToChar(source));
|
||||
return shortNameSource;
|
||||
if (!isempty(shortNameSource))
|
||||
return shortNameSource;
|
||||
}
|
||||
return shortName;
|
||||
}
|
||||
@ -140,15 +153,18 @@ int cChannel::Transponder(int Frequency, char Polarization)
|
||||
|
||||
int cChannel::Transponder(void) const
|
||||
{
|
||||
int tf = frequency;
|
||||
while (tf > 20000)
|
||||
tf /= 1000;
|
||||
if (IsSat()) {
|
||||
const char *p = strpbrk(parameters, "HVLRhvlr"); // lowercase for backwards compatibility
|
||||
if (p)
|
||||
tf = Transponder(tf, *p);
|
||||
if (!transponder) {
|
||||
int tf = frequency;
|
||||
while (tf > 20000)
|
||||
tf /= 1000;
|
||||
if (IsSat()) {
|
||||
const char *p = strpbrk(parameters, "HVLRhvlr"); // lowercase for backwards compatibility
|
||||
if (p)
|
||||
tf = Transponder(tf, *p);
|
||||
}
|
||||
transponder = tf;
|
||||
}
|
||||
return tf;
|
||||
return transponder;
|
||||
}
|
||||
|
||||
int cChannel::Modification(int Mask) const
|
||||
@ -162,6 +178,7 @@ void cChannel::CopyTransponderData(const cChannel *Channel)
|
||||
{
|
||||
if (Channel) {
|
||||
frequency = Channel->frequency;
|
||||
transponder = Channel->transponder;
|
||||
source = Channel->source;
|
||||
srate = Channel->srate;
|
||||
parameters = Channel->parameters;
|
||||
@ -190,11 +207,11 @@ bool cChannel::SetTransponderData(int Source, int Frequency, int Srate, const ch
|
||||
cString OldTransponderData = TransponderDataToString();
|
||||
source = Source;
|
||||
frequency = Frequency;
|
||||
transponder = 0;
|
||||
srate = Srate;
|
||||
parameters = Parameters;
|
||||
schedule = NULL;
|
||||
nameSource = NULL;
|
||||
shortNameSource = NULL;
|
||||
UpdateNameSource();
|
||||
if (Number() && !Quiet) {
|
||||
dsyslog("changing transponder data of channel %d (%s) from %s to %s", Number(), name, *OldTransponderData, *TransponderDataToString());
|
||||
modification |= CHANNELMOD_TRANSP;
|
||||
@ -259,14 +276,12 @@ bool cChannel::SetName(const char *Name, const char *ShortName, const char *Prov
|
||||
dsyslog("changing name of channel %d from '%s,%s;%s' to '%s,%s;%s'", Number(), name, shortName, provider, Name, ShortName, Provider);
|
||||
modification |= CHANNELMOD_NAME;
|
||||
}
|
||||
if (nn) {
|
||||
if (nn)
|
||||
name = strcpyrealloc(name, Name);
|
||||
nameSource = NULL;
|
||||
}
|
||||
if (ns) {
|
||||
if (ns)
|
||||
shortName = strcpyrealloc(shortName, ShortName);
|
||||
shortNameSource = NULL;
|
||||
}
|
||||
if (nn || ns)
|
||||
UpdateNameSource();
|
||||
if (np)
|
||||
provider = strcpyrealloc(provider, Provider);
|
||||
return true;
|
||||
@ -648,6 +663,7 @@ bool cChannel::Parse(const char *s)
|
||||
if (parambuf && sourcebuf && vpidbuf && apidbuf) {
|
||||
parameters = parambuf;
|
||||
ok = (source = cSource::FromString(sourcebuf)) >= 0;
|
||||
transponder = 0;
|
||||
|
||||
char *p;
|
||||
if ((p = strchr(vpidbuf, '=')) != NULL) {
|
||||
@ -791,8 +807,7 @@ bool cChannel::Parse(const char *s)
|
||||
free(tpidbuf);
|
||||
free(caidbuf);
|
||||
free(namebuf);
|
||||
nameSource = NULL;
|
||||
shortNameSource = NULL;
|
||||
UpdateNameSource();
|
||||
if (!GetChannelID().Valid()) {
|
||||
esyslog("ERROR: channel data results in invalid ID!");
|
||||
return false;
|
||||
@ -833,7 +848,7 @@ int cChannels::maxChannelNameLength = 0;
|
||||
int cChannels::maxShortChannelNameLength = 0;
|
||||
|
||||
cChannels::cChannels(void)
|
||||
:cConfig<cChannel>("Channels")
|
||||
:cConfig<cChannel>("2 Channels")
|
||||
{
|
||||
modifiedByUser = 0;
|
||||
}
|
||||
@ -938,6 +953,25 @@ void cChannels::ReNumber(void)
|
||||
}
|
||||
}
|
||||
|
||||
bool cChannels::MoveNeedsDecrement(cChannel *From, cChannel *To)
|
||||
{
|
||||
int Number = From->Number();
|
||||
if (Number < To->Number()) {
|
||||
for (cChannel *Channel = Next(From); Channel; Channel = Next(Channel)) {
|
||||
if (Channel == To)
|
||||
break;
|
||||
if (Channel->GroupSep()) {
|
||||
if (Channel->Number() > Number)
|
||||
Number = Channel->Number();
|
||||
}
|
||||
else
|
||||
Number++;
|
||||
}
|
||||
return Number == To->Number();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cChannels::Del(cChannel *Channel)
|
||||
{
|
||||
UnhashChannel(Channel);
|
||||
@ -1093,8 +1127,8 @@ bool cChannels::MarkObsoleteChannels(int Source, int Nid, int Tid)
|
||||
bool ChannelsModified = false;
|
||||
for (cChannel *Channel = First(); Channel; Channel = Next(Channel)) {
|
||||
if (time(NULL) - Channel->Seen() > CHANNELTIMEOBSOLETE && Channel->Source() == Source && Channel->Nid() == Nid && Channel->Tid() == Tid && Channel->Rid() == 0) {
|
||||
bool OldShowChannelNamesWithSource = Setup.ShowChannelNamesWithSource;
|
||||
Setup.ShowChannelNamesWithSource = false;
|
||||
int OldShowChannelNamesWithSource = Setup.ShowChannelNamesWithSource;
|
||||
Setup.ShowChannelNamesWithSource = 0;
|
||||
if (!endswith(Channel->Name(), CHANNELMARKOBSOLETE))
|
||||
ChannelsModified |= Channel->SetName(cString::sprintf("%s %s", Channel->Name(), CHANNELMARKOBSOLETE), Channel->ShortName(), cString::sprintf("%s %s", CHANNELMARKOBSOLETE, Channel->Provider()));
|
||||
Setup.ShowChannelNamesWithSource = OldShowChannelNamesWithSource;
|
||||
|
229
channels.conf
229
channels.conf
@ -1,85 +1,162 @@
|
||||
RTL Television,RTL;RTL World:12187:HC34M2S0:S19.2E:27500:163=2:104=deu@3;106=deu@106:105;110=deu:0:12003:1:1089:0
|
||||
RTL Television,RTL;CBC:12187:HC34M2S0:S19.2E:27500:163=2:104=deu@3;106=deu@106:105;110=deu:0:12003:1:1089:0
|
||||
SAT.1;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:255=2:256=deu@3;259=deu@106:32:0:17500:1:1107:0
|
||||
ProSieben;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:511=2:512=deu@3;515=deu@106:33:0:17501:1:1107:0
|
||||
RTL2;RTL World:12187:HC34M2S0:S19.2E:27500:166=2:128=deu@3:68:0:12020:1:1089:0
|
||||
RTL2;CBC:12187:HC34M2S0:S19.2E:27500:166=2:128=deu@3:68;75=deu:0:12020:1:1089:0
|
||||
:ARD und ZDF
|
||||
Das Erste HD;ARD:11493:HC23M5O35P0S1:S19.2E:22000:5101=27:5102=deu@3,5103=mis@3;5106=deu@106:5104;5105=deu:0:10301:1:1019:0
|
||||
ZDF HD;ZDFvision:11362:HC23M5O35P0S1:S19.2E:22000:6110=27:6120=deu@3,6121=mis@3,6123=mul@3;6122=deu@106:6130;6131=deu:0:11110:1:1011:0
|
||||
BR Süd HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5201=27:5202=deu@3,5203=mis@3;5206=deu@106:5204:0:10325:1:1025:0
|
||||
hr-fernsehen;ARD:11836:HC34M2S0:S19.2E:27500:301=2:302=deu@3,303=mis@3:304:0:28108:1:1101:0
|
||||
NDR FS MV HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5221=27:5222=deu@3,5223=mis@3;5226=deu@106:5224;5225=deu:0:10328:1:1025:0
|
||||
SR Fernsehen;ARD:12265:HC34M2S0:S19.2E:27500:1301=2:1302=deu@3,1303=mis@3:1304:0:28486:1:1093:0
|
||||
WDR HD Köln;ARD:12422:HC34M2S0:S19.2E:27500:5501=27:5502=deu@3,5503=mis@3;5506=deu@106:5504:0:28325:1:1201:0
|
||||
:Dritte Programme
|
||||
BR Fernsehen Sued HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5201=27:5202=deu@3,5203=mis@3;5206=deu@106:5204;5205=deu:0:10325:1:1025:0
|
||||
hr-fernsehen HD;ARD:10891:HC23M5O35P0S1:S19.2E:22000:5351=27:5352=deu@3,5353=mis@3;5356=deu@106:5354;5355=deu:0:10355:1:1061:0
|
||||
NDR FS NDS HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5221=27:5222=deu@3,5223=mis@3;5226=deu@106:5224;5225=deu:0:10327:1:1025:0
|
||||
WDR HD Koeln;ARD:12422:HC34M2S0:S19.2E:27500:5501=27:5502=deu@3,5503=mis@3;5506=deu@106:5504;5505=deu:0:28325:1:1201:0
|
||||
SWR BW HD;ARD:11493:HC23M5O35P0S1:S19.2E:22000:5121=27:5122=deu@3,5123=mis@3;5126=deu@106:5124;5125=deu:0:10303:1:1019:0
|
||||
rbb Berlin;ARD:12109:HC34M2S0:S19.2E:27500:601=2:602=deu@3,603=mis@3:604:0:28206:1:1073:0
|
||||
rbb Berlin HD;ARD:10891:HC23M5O35P0S1:S19.2E:22000:5311=27:5312=deu@3,5313=mis@3;5316=deu@106:5314;5315=deu:0:10351:1:1061:0
|
||||
MDR Sachsen HD;ARD:10891:HC23M5O35P0S1:S19.2E:22000:5331=27:5332=deu@3,5333=mis@3;5336=deu@106:5334;5335=deu:0:10352:1:1061:0
|
||||
PHOENIX HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5261=27:5262=deu@3,5263=mul@3:5264:0:10331:1:1025:0
|
||||
BR-alpha;ARD:12265:HC34M2S0:S19.2E:27500:1401=2:1402=deu@3,1403=mis@3;1406=deu@106:1404:0:28487:1:1093:0
|
||||
ARD-alpha;ARD:12265:HC34M2S0:S19.2E:27500:1401=2:1402=deu@3,1403=mis@3;1406=deu@106:1404;1405=deu:0:28487:1:1093:0
|
||||
3sat HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6510=27:6520=deu@3,6521=mis@3,6523=mul@3;6522=deu@106:6530;6531=deu:0:11150:1:1010:0
|
||||
arte HD;ARD:11493:HC23M5O35P0S1:S19.2E:22000:5111=27:5112=deu@3,5113=fra@3;5116=deu@106:5114;5115=deu,5118=fra:0:10302:1:1019:0
|
||||
MDR Sachsen;ARD:12109:HC34M2S0:S19.2E:27500:2901=2:2902=deu@3,2903=mis@3:2904:0:28228:1:1073:0
|
||||
ServusTV HD Oesterreich;ServusTV:11303:HC23M5O35P0S1:S19.2E:22000:3583=27:3584=deu@4,3585=eng@4;3586=deu@122,3587=deu@106:3588:0:4913:1:1007:0
|
||||
N24;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:1023=2:1024=deu@3:35:0:17503:1:1107:0
|
||||
Das Erste;ARD:11836:HC34M2S0:S19.2E:27500:101=2:102=deu@3,103=mis@3;106=deu@106:104;105=deu:0:28106:1:1101:0
|
||||
Bayerisches FS Süd;ARD:11836:HC34M2S0:S19.2E:27500:201=2:202=deu@3,203=mis@3;206=deu@106:204:0:28107:1:1101:0
|
||||
NDR FS MV;ARD:12109:HC34M2S0:S19.2E:27500:2601=2:2602=deu@3,2603=mis@3:2604:0:28224:1:1073:0
|
||||
WDR Köln;ARD:11836:HC34M2S0:S19.2E:27500:601=2:602=deu@3,603=mis@3:604:0:28111:1:1101:0
|
||||
SWR Fernsehen BW;ARD:11836:HC34M2S0:S19.2E:27500:801=2:802=deu@3,803=mis@3;806=deu@106:804:0:28113:1:1101:0
|
||||
PHOENIX;ARD:10744:HC56M2S0:S19.2E:22000:501=2:502=deu@3,503=mul@3:504:0:28725:1:1051:0
|
||||
ZDF;ZDFvision:11953:HC34M2S0:S19.2E:27500:110=2:120=deu@3,121=mis@3,122=mul@3;125=deu@106:130;131=deu:0:28006:1:1079:0
|
||||
3sat;ZDFvision:11953:HC34M2S0:S19.2E:27500:210=2:220=deu@3,221=mis@3,222=mul@3;225=deu@106:230;231=deu:0:28007:1:1079:0
|
||||
KiKA HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6610=27:6620=deu@3,6621=mis@3;6622=deu@106:6630:0:11160:1:1010:0
|
||||
KiKA;ZDFvision:11953:HC34M2S0:S19.2E:27500:310=2:320=deu@3,321=mis@3;325=deu@106:330:0:28008:1:1079:0
|
||||
arte;ARD:10744:HC56M2S0:S19.2E:22000:401=2:402=deu@3,403=fra@3:404:0:28724:1:1051:0
|
||||
ORF1 HD;ORF:11303:HC23M5O35P0S1:S19.2E:22000:1920=27:1921=deu@4,1922=eng@4;1923=deu@106:1925:D05,D95,648,1702,1833,9C4,98C:4911:1:1007:0
|
||||
ORF1;ORF:12692:HC56M2S0:S19.2E:22000:160=2:161=deu@3;163=deu@106:165:D05,D95,648,1702,1833,9C4,98C:13001:1:1117:0
|
||||
ORF2 HD;ORF:11303:HC23M5O35P0S1:S19.2E:22000:2920=27:2921=deu@4,2922=eng@4;2923=deu@106:2925:D05,D95,648,1702,1833,9C4,98C:4912:1:1007:0
|
||||
ORF2;ORF:12692:HC56M2S0:S19.2E:22000:500=2:501=deu@3;503=deu@106:505:D95,D05,648,1702,1833,9C4,98C:13002:1:1117:0
|
||||
ZDFinfo HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6710=27:6720=deu@3,6721=mis@3,6723=mul@3;6722=deu@106:6730:0:11170:1:1010:0
|
||||
ZDFinfo;ZDFvision:11953:HC34M2S0:S19.2E:27500:610=2:620=deu@3,621=mis@3,622=mul@3;625=deu@106:630:0:28011:1:1079:0
|
||||
CNN Int.;CNN:11778:VC34M2S0:S19.2E:27500:165=2:100=eng@3:0:0:28522:1:1068:0
|
||||
SUPER RTL;RTL World:12187:HC34M2S0:S19.2E:27500:165=2:120=deu@3:65:0:12040:1:1089:0
|
||||
VOX;RTL World:12187:HC34M2S0:S19.2E:27500:167=2:136=deu@3:71;74=deu:0:12060:1:1089:0
|
||||
kabel eins;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:767=2:768=deu@3:34:0:17502:1:1107:0
|
||||
DAS VIERTE,D VIERTE;BetaDigital:12460:HC34M2S0:S19.2E:27500:2047=2:2048=deu@3:36:0:1793:133:5:0
|
||||
BBC FOUR;BSkyB:10802:HC56M2S0:S28.2E:22000:5600=2:5601=eng@3,5602=NAR@3:5603;5604=eng:0:6416:2:2047:0
|
||||
BBC HD;BSkyB:10847:vC56M2O0S1:S28.5E:23000:5500=27:5502=NAR@3;5501=eng@106:5503;5504=eng:0:6940:2:2050:0
|
||||
BBC One HD;BSkyB:10847:VC23M5O25P0S1:S28.2E:23000:5400=27:5402=NAR@3;5401=eng@106:5403;5404=eng:0:6941:2:2050:0
|
||||
SAT.1 Gold;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:1279=2:1280=deu@3:36:0:17504:1:1107:0
|
||||
arte HD;ARD:11493:HC23M5O35P0S1:S19.2E:22000:5111=27:5112=deu@3,5113=fra@3,5117=mis@3;5116=mul@106:5114;5115=deu,5118=fra,5119=deu:0:10302:1:1019:0
|
||||
zdf_neo HD;ZDFvision:11362:HC23M5O35P0S1:S19.2E:22000:6310=27:6320=deu@3,6321=mis@3,6323=mul@3;6322=deu@106:6330;6331=deu:0:11130:1:1011:0
|
||||
ZDFinfo HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6710=27:6720=deu@3,6721=mis@3,6723=mul@3;6722=deu@106:6730;6731=deu:0:11170:1:1010:0
|
||||
ONE HD;ARD:11052:HC23M5O35P0S1:S19.2E:22000:5411=27:5412=deu@3,5413=mis@3;5416=deu@106:5414;5415=deu:0:10376:1:1039:0
|
||||
KiKA HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6610=27:6620=deu@3,6621=mis@3;6622=deu@106:6630;6631=deu:0:11160:1:1010:0
|
||||
:Regionalprogramme
|
||||
Niederbayern;MB Satellite:11523:HC56M2S0:S19.2E:22000:2559=2:2560=deu@3:0:0:4609:1:1021:0
|
||||
Franken Fernsehen;MB Satellite:11523:HC56M2S0:S19.2E:22000:511=2:512=deu@3:0:0:4601:1:1021:0
|
||||
muenchen.tv;MB Satellite:11523:HC56M2S0:S19.2E:22000:1279=2:1280=deu@3:0:0:4604:1:1021:0
|
||||
Mainfranken;MB Satellite:11523:HC56M2S0:S19.2E:22000:1791=2:1792=deu@3:0:0:4606:1:1021:0
|
||||
TV Oberfranken;MB Satellite:11523:HC56M2S0:S19.2E:22000:2047=2:2048=deu@3:0:0:4607:1:1021:0
|
||||
TVA-OTV;MB Satellite:11523:HC56M2S0:S19.2E:22000:2303=2:2304=deu@3:0:0:4608:1:1021:0
|
||||
a.tv;MB Satellite:11523:HC56M2S0:S19.2E:22000:255=2:256=deu@3:0:0:4600:1:1021:0
|
||||
BR Fernsehen Nord HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5201=27:5202=deu@3,5203=mis@3;5206=deu@106:5204;5205=deu:0:10326:1:1025:0
|
||||
rbb Brandenburg HD;ARD:10891:HC23M5O35P0S1:S19.2E:22000:5311=27:5312=deu@3,5313=mis@3;5316=deu@106:5314;5315=deu:0:10350:1:1061:0
|
||||
SR Fernsehen HD;ARD:11052:HC23M5O35P0S1:S19.2E:22000:5431=27:5432=deu@3,5433=mis@3;5436=deu@106:5434;5435=deu:0:10378:1:1039:0
|
||||
Radio Bremen TV;ARD:12421:HC34M2S0:S19.2E:27500:1201=2:1202=deu@3:1204:0:28385:1:1201:0
|
||||
:Oesterreichisches Fernsehen
|
||||
ORF1 HD;ORF:11303:HC23M5O35P0S1:S19.2E:22000:1920=27:0;1921=deu@106,1922=mis@106:1925:648,650,D95,D98,6E2,500,9C4,98C:4911:1:1007:0
|
||||
ORF2W HD;ORF:11303:HC23M5O35P0S1:S19.2E:22000:2920=27:0;2921=deu@106,2922=mis@106:2925:648,650,D95,D98,6E2,500,9C4,98C:4912:1:1007:0
|
||||
ORF III;ORF:12662:HC56M2S0:S19.2E:22000:1010=2:1011=deu@4:1013:648,650,D95,D98,9C4,98C:13101:1:1115:0
|
||||
ServusTV HD Oesterreich;ServusTV:11303:HC23M5O35P0S1:S19.2E:22000:3583=27:3584=deu@4,3585=eng@4;3587=deu@106:3588:648,650,D95,D98,9C4,98C,6E2,500:4913:1:1007:0
|
||||
ServusTV HD Deutschland;ServusTV:11303:HC23M5O35P0S1:S19.2E:22000:4920=27:4921=deu@4,4922=eng@4;4924=deu@106:4925:0:4914:1:1007:0
|
||||
ATV;ATV+:12692:HC56M2S0:S19.2E:22000:506=2:507=deu@3:509:648,650,D95,D98,9C4,98C:13012:1:1117:0
|
||||
ORF SPORT+;ORF:11243:HC56M2S0:S19.2E:22000:2210=2:2211=deu@3,2212=mis@3:2215:648,650,D95,D98,9C4,98C:13221:1:1003:0
|
||||
PULS 4 Austria;ProSiebenSat.1:12051:VC34M2S0:S19.2E:27500:1791=2:1792=deu@3:39:9C4,98C,D95,648,D98,650,500,6E2,98D:20007:1:1082:0
|
||||
:Nachrichten
|
||||
tagesschau24 HD;ARD:11052:HC23M5O35P0S1:S19.2E:22000:5401=27:5402=deu@3,5403=mis@3;5406=deu@106:5404:0:10375:1:1039:0
|
||||
n-tv;CBC:12187:HC34M2S0:S19.2E:27500:169=2:73=deu@3,77=mul@3:80:0:12090:1:1089:0
|
||||
WELT;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:1023=2:1024=deu@3:35:0:17503:1:1107:0
|
||||
N24 DOKU;BetaDigital:12460:HC34M2S0:S19.2E:27500:511=2:512=deu@3:34:0:48:133:5:0
|
||||
CNN Int.;Harmonic:11626:VC56M2S0:S19.2E:22000:165=2:100=eng@3:0:0:4422:1:1028:0
|
||||
EURONEWS FRENCH SD;Globecast:12226:HC34M2S0:S19.2E:27500:2432=2:2435=fra@3:0:0:31220:1:1091:0
|
||||
Bloomberg Europe TV;Bloomberg TV:11597:VC56M2S0:S19.2E:22000:1360=2:1320=eng@3:0:0:10067:1:1026:0
|
||||
CNBC Europe;CNBC:11597:VC56M2S0:S19.2E:22000:307=2:308=eng@3:0:0:10030:1:1026:0
|
||||
Russia Today;GLOBECAST:11538:VC56M2S0:S19.2E:22000:604=2:624=eng@3:0:0:6904:1:1022:0
|
||||
Sky News Intl;SES ASTRA:12604:HC56M2S0:S19.2E:22000:1290=2:2290=eng@3:1750:0:7290:1:1111:0
|
||||
Al Jazeera English;Al Jazeera:11626:VC56M2S0:S19.2E:22000:3505=2:3625=eng@3:0:0:4440:1:1028:0
|
||||
Al Jazeera Channel;GLOBECAST:11508:VC56M2S0:S19.2E:22000:709=2:729=ara@3:0:0:7009:1:1020:0
|
||||
:Sport
|
||||
SPORT1;BetaDigital:12480:VC34M2S0:S19.2E:27500:1023=2:1024=deu@3:39:0:900:133:33:0
|
||||
HSE24,HSE24;BetaDigital:12480:VC34M2S0:S19.2E:27500:1279=2:1280=deu@3:37:0:40:133:33:0
|
||||
Bloomberg Europe TV;Arqiva:11597:VC56M2S0:S19.2E:22000:1360=2:1320=eng@4:37:0:10067:1:1026:0
|
||||
NRJ 12;CSAT:11817:VC34M2S0:S19.2E:27500:163=2:92=fra@4;93=fra@106:41:1811,1812,500,1863,100:8004:1:1070:0
|
||||
rbb Brandenburg;ARD:12109:HC34M2S0:S19.2E:27500:601=2:602=deu@3,603=mis@3:604:0:28205:1:1073:0
|
||||
Sky News Intl;SES ASTRA:12604:HC56M2S0:S19.2E:22000:1290=2:2290=@4:0:0:7290:1:1111:0
|
||||
Veronica/DisneyXD;CANALDIGITAAL:12574:HC56M2O0S0:S19.2E:22000:0:0:0:622:5020:53:1109:0
|
||||
Test;CANALDIGITAAL:12574:HC56M2O0S0:S19.2E:22000:522+8190=2:97=dut@4:40:100:5025:53:1109:0
|
||||
n-tv;RTL World:12187:HC34M2S0:S19.2E:27500:169=2:73=deu@3:80:0:12090:1:1089:0
|
||||
Al Jazeera Channel;GlobeCast:11508:VC56M2S0:S19.2E:22000:709=2:729=ara@3:0:0:7009:1:1020:0
|
||||
ORF III;ORF:12662:HC56M2S0:S19.2E:22000:1010=2:1011=deu@4:1013:D95,648,D05,9C4,1702,1833,98C:13101:1:1115:0
|
||||
Eurosport HD,EurospHD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:1535=27:0;1539=deu@106:32:1833,9C4,9AF,98C:132:133:6:0
|
||||
Eurosport Deutschland;SES Astra:12226:HC34M2S0:S19.2E:27500:101=2:103=deu@4:102:0:31200:1:1091:0
|
||||
tagesschau24;ARD:10744:HC56M2S0:S19.2E:22000:101=2:102=deu@3:0:0:28721:1:1051:0
|
||||
Einsfestival HD;ARD:12422:HC34M2S0:S19.2E:27500:1601=27:1602=deu@3;1606=deu@106:1604:0:28396:1:1201:0
|
||||
Einsfestival;ARD:10744:HC56M2S0:S19.2E:22000:201=2:202=deu@3,203=mis@3;206=deu@106:204:0:28722:1:1051:0
|
||||
EinsPlus;ARD:10744:HC56M2S0:S19.2E:22000:301=2:302=deu@3,303=mis@3;306=deu@106:304:0:28723:1:1051:0
|
||||
zdf.kultur HD;ZDFvision:11362:HC23M5O35P0S1:S19.2E:22000:6410=27:6420=deu@3,6421=mis@3,6423=mul@3;6422=deu@106:6430:0:11140:1:1011:0
|
||||
zdf.kultur;ZDFvision:11953:HC34M2S0:S19.2E:27500:1110=2:1120=deu@3,1121=mis@3,1122=mul@3;1125=deu@106:1130:0:28016:1:1079:0
|
||||
zdf_neo HD;ZDFvision:11362:HC23M5O35P0S1:S19.2E:22000:6310=27:6320=deu@3,6321=mis@3,6323=mul@3;6322=deu@106:6330:0:11130:1:1011:0
|
||||
zdf_neo;ZDFvision:11953:HC34M2S0:S19.2E:27500:660=2:670=deu@3,671=mis@3,672=mul@3;675=deu@106:680:0:28014:1:1079:0
|
||||
Eurosport 1 Deutschland;SES Astra:12226:HC34M2S0:S19.2E:27500:101=2:103=deu@4:102:0:31200:1:1091:0
|
||||
:Privatsender
|
||||
RTLplus;CBC:12187:HC34M2S0:S19.2E:27500:168=2:137=deu@3:70:0:12080:1:1089:0
|
||||
NITRO;CBC:12187:HC34M2S0:S19.2E:27500:173=2:146=deu@3:84;86=deu:0:12061:1:1089:0
|
||||
SUPER RTL;CBC:12187:HC34M2S0:S19.2E:27500:165=2:120=deu@3:65;66=deu:0:12040:1:1089:0
|
||||
SAT.1 Gold;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:1279=2:1280=deu@3:36:0:17504:1:1107:0
|
||||
Pro7 MAXX;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:1535=2:1536=deu@3:37:0:17505:1:1107:0
|
||||
kabel eins;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:767=2:768=deu@3:34:0:17502:1:1107:0
|
||||
kabel eins Doku;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:2559=2:2560=deu@3:41:0:17509:1:1107:0
|
||||
Family TV;BetaDigital:10920:HC78M2S0:S19.2E:22000:255=2:256=deu@3:0:0:33:133:15:0
|
||||
Disney Channel;BetaDigital:12460:HC34M2S0:S19.2E:27500:2047=2:2048=deu@3;2051=deu@106:36:0:1793:133:5:0
|
||||
TELE 5;BetaDigital:12480:VC34M2S0:S19.2E:27500:1535=2:1536=deu@3:38:0:51:133:33:0
|
||||
VOX;CBC:12187:HC34M2S0:S19.2E:27500:167=2:136=deu@3:71;74=deu:0:12060:1:1089:0
|
||||
SIXX;ProSiebenSat.1:12460:HC34M2S0:S19.2E:27500:767=2:768=deu@3:35:0:776:133:5:0
|
||||
:Sky
|
||||
Sky Cinema,Cinema;SKY:11797:HC34M2S0:S19.2E:27500:511=2:512=deu@3,513=eng@3;515=deu@106:32:1702,1722,1833,1834,1836,9C4,9C7,9AF,98C,1861:10:133:2:0
|
||||
Sky Cinema +1,Cinema1;SKY:11797:HC34M2S0:S19.2E:27500:1791=2:1792=deu@3,1793=eng@3;1795=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:11:133:2:0
|
||||
Sky Cinema +24,Cinema24;SKY:11797:HC34M2S0:S19.2E:27500:2303=2:2304=deu@3,2305=eng@3;2307=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:43:133:2:0
|
||||
Sky Action,Action;SKY:11797:HC34M2S0:S19.2E:27500:767=2:768=deu@3,769=eng@3;771=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:9:133:2:0
|
||||
Sky Comedy,Comedy;SKY:11797:HC34M2S0:S19.2E:27500:2559=2:2560=deu@3,2561=eng@3;2563=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:8:133:2:0
|
||||
Sky Atlantic HD,AtlanticHD;SKY:11993:HC910M2O35P0S1:S19.2E:27500:1279=27:0;1283=deu@106,1284=eng@106:32:1833,9C4,9AF,98C:110:133:13:0
|
||||
Fox Serie,Fox;SKY:12070:HC34M2S0:S19.2E:27500:1279=2:1280=deu@3,1281=eng@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:16:133:1:0
|
||||
History HD,HistHD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:767=27:0;771=deu@106:32:1833,9C4,9AF,98C:113:133:13:0
|
||||
Sky Emotion,Emotion;SKY:11797:HC34M2S0:S19.2E:27500:2815=2:2816=deu@3,2817=eng@3;2819=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:20:133:2:0
|
||||
Sky Nostalgie,Nostalgie;SKY:11719:HC34M2S0:S19.2E:27500:1535=2:1536=deu@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:516:133:3:0
|
||||
Sky Hits,SkyHits;SKY:11719:HC34M2S0:S19.2E:27500:1023=2:1024=deu@3,1025=eng@3;1027=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:41:133:3:0
|
||||
Discovery Channel,Discovery;SKY:12031:HC34M2S0:S19.2E:27500:3071=2:3072=deu@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:14:133:4:0
|
||||
National Geographic,NatGeo;SKY:12031:HC34M2S0:S19.2E:27500:3327=2:3328=deu@3,3329=eng@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:13:133:4:0
|
||||
Disney Channel,Disney;SKY:11758:HC34M2S0:S19.2E:27500:2559=2:2560=deu@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:34:133:17:0
|
||||
TNT Serie,TNTSerie;SKY:12070:HC34M2S0:S19.2E:27500:2559=2:2560=deu@3,2561=eng@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:50:133:1:0
|
||||
:@1000 New channels
|
||||
DMAX;BetaDigital:12480:VC34M2S0:S19.2E:27500:3327=2:3328=deu@3:44:0:63:133:33:0
|
||||
ANIXE HD;BetaDigital:10773:HC34M5O20P0S1:S19.2E:22000:255=27:0;259=deu@106:0:0:21100:1:1053:0
|
||||
Nickelodeon;MTV Networks Europe:11973:VC34M2S0:S19.2E:27500:4101=2:4102=deu@4,4103=eng@4:4104:0:28680:1:1078:0
|
||||
TOGGO plus;CBC:12187:HC34M2S0:S19.2E:27500:301=2:303=deu@3:0:0:12030:1:1089:0
|
||||
Comedy Central/VIVA;MTV Networks Europe:11973:VC34M2S0:S19.2E:27500:4061=2:4062=@4:4064:0:28676:1:1078:0
|
||||
DELUXE MUSIC,DELUXE;BetaDigital:12148:HC34M2S0:S19.2E:27500:3327=2:3328=deu@3:0:0:65:133:7:0
|
||||
sonnenklar.TV HD;BetaDigital:12574:HC23M5O35P0S1:S19.2E:22000:255=27:0;259=deu@106:32:0:5400:1:1109:0
|
||||
QVC Deutschland;SES ASTRA:12551:VC56M2S0:S19.2E:22000:165=2:166=deu@3:167:0:12100:1:1108:0
|
||||
HSE24,HSE24;BetaDigital:12480:VC34M2S0:S19.2E:27500:1279=2:1280=deu@3:37:0:40:133:33:0
|
||||
1-2-3.tv HD;BetaDigital:10802:HC34M5O35P0S1:S19.2E:22000:767=27:0;771=deu@106:34:0:5502:1:1055:0
|
||||
Juwelo HD;BetaDigital:12574:HC23M5O35P0S1:S19.2E:22000:1023=27:1024=deu@3:0:0:5403:1:1109:0
|
||||
:@100
|
||||
:Sky HD
|
||||
Sky Cinema HD,Sky Cinema HD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:1279=27:0;1283=deu@106,1284=eng@106:0:98C,9C4,9AF,98D:131:133:6:0
|
||||
Sky Cinema +1 HD,Sky Cine1 HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:255=27:0;259=deu@106,260=eng@106:0:9C4,98C,9AF,98D:134:133:8:0
|
||||
Sky Cinema +24 HD,Sky Cine24 HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:9C4,98C,9AF,98D:135:133:8:0
|
||||
Sky Cinema Hits HD,Sky Hits HD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:767=27:0;771=deu@106:0:9C4,98C,9AF,98D:107:133:12:0
|
||||
Sky Cinema Action HD,Action HD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:1023=27:0;1027=deu@106,1028=eng@106:0:98C,9C4,9AF,98D:116:133:11:0
|
||||
Sky Cinema Animation HD,Animation HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:767=27:0;771=deu@106,772=eng@106:0:9C4,98C,9AF,98D:139:133:8:0
|
||||
SYFY HD,SYFY HD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:9C4,98C,9AF,98D:126:133:12:0
|
||||
Sky Atlantic HD,AtlanticHD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:1279=27:0;1283=deu@106,1284=eng@106:0:98C,9C4,9AF,98D:110:133:13:0
|
||||
Sky 1 +1 HD,Sky 1 +1 HD;SKY:11797:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:98C,9C4,9AF,98D:144:133:16:0
|
||||
TNT Serie HD,TNTSerieHD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:255=27:0;259=deu@106,260=eng@106:0:98C,9C4,9AF,98D:123:133:11:0
|
||||
TNT Comedy HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:98C,9C4,98D:136:133:14:0
|
||||
Fox HD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:1023=27:0;1027=deu@106,1028=eng@106:0:98C,9C4,98D:124:133:10:0
|
||||
13th Street HD,13th St HD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:767=27:0;771=deu@106,772=eng@106:0:98C,9C4,9AF,98D:127:133:13:0
|
||||
Universal HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:1535=27:0;1539=deu@106,1540=eng@106:0:98C,9C4,98D:101:133:14:0
|
||||
RTL Crime HD,RTL CrimeHD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:255=27:0;259=deu@106,260=eng@106:0:9C4,98C,98D:140:133:9:0
|
||||
E! Entertainm. HD,E! HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:255=27:0;259=deu@106,260=eng@106:0:98C,9C4,98D:128:133:14:0
|
||||
Spiegel Geschichte HD,Spiegel G HD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:255=27:0;259=deu@106:0:98C,9C4,98D:137:133:10:0
|
||||
Discovery HD,DiscHD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:1023=27:0;1027=deu@106,1028=eng@106:0:98C,9C4,9AF,98D:130:133:6:0
|
||||
History HD,HistHD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:767=27:0;771=deu@106,772=eng@106:0:98C,9C4,9AF,98D:113:133:11:0
|
||||
NatGeo HD,NatGeoHD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:98C,9C4,9AF,98D:112:133:13:0
|
||||
Nat Geo Wild HD,NGWildHD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:98C,9C4,9AF,98D:118:133:6:0
|
||||
Disney Cinemagic HD,DisneyCinHD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:255=27:0;259=deu@106,260=eng@106:0:98C,9C4,9AF,98D:111:133:13:0
|
||||
Disney Junior HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:1279=27:0;1283=deu@106:0:9C4,98C,9AF,98D:138:133:8:0
|
||||
Sky Arts HD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:767=27:0;771=deu@106,772=eng@106:0:9C4,98C,98D:145:133:9:0
|
||||
:Sky Film
|
||||
Sky Cinema Comedy,Sky Comedy;SKY:11719:HC910M2O35P0S1:S19.2E:27500:1023=27:1024=deu@3,1025=eng@3;1027=deu@106:0:9C4,98C,9AF,98D:8:133:3:0
|
||||
Sky Cinema Western,Sky Western;SKY:12031:HC910M2O35P0S1:S19.2E:27500:767=27:768=deu@3,769=eng@3:0:9C4,98C,9AF,98D:516:133:4:0
|
||||
Sky Cinema Emotion,Sky Emotion;SKY:12031:HC910M2O35P0S1:S19.2E:27500:511=27:512=deu@3,513=eng@3;515=deu@106:0:9C4,98C,9AF,98D:20:133:4:0
|
||||
:Sky Welt
|
||||
RTL Passion,Passion;SKY:12031:HC910M2O35P0S1:S19.2E:27500:3839=27:3840=deu@3,3841=eng@3:0:9C4,98C,9AF,98D:29:133:4:0
|
||||
Sky Krimi,SkyKrimi;SKY:12031:HC910M2O35P0S1:S19.2E:27500:1535=27:1536=deu@3:0:9C4,98C,9AF,98D:23:133:4:0
|
||||
Disney XD,DisneyXD;SKY:11719:HC910M2O35P0S1:S19.2E:27500:1279=27:1280=deu@3,1281=eng@3:0:9C4,98C,9AF,98D:28:133:3:0
|
||||
Heimatkanal,Heimat;SKY:11758:HC910M2O35P0S1:S19.2E:27500:2815=27:2816=deu@3:0:9C4,98C,9AF,98D:22:133:2:0
|
||||
Romance TV,Romance;SKY:11758:HC910M2O35P0S1:S19.2E:27500:3071=27:3072=deu@3:0:9C4,98C,9AF,98D:518:133:2:0
|
||||
Classica;SKY:11719:HC910M2O35P0S1:S19.2E:27500:2047=27:2048=deu@3:0:9C4,98C,9AF,98D:24:133:3:0
|
||||
:Sky Welt Extra
|
||||
TNT Film (TCM),TNT Film;SKY:11914:HC910M2O35P0S1:S19.2E:27500:4351=27:4352=deu@3,4353=eng@3:0:98C,9C4,9AF,98D:405:133:6:0
|
||||
Kinowelt TV,Kinowelt;SKY:12031:HC910M2O35P0S1:S19.2E:27500:4351=27:4352=deu@3:0:9C4,98C,9AF,98D:406:133:4:0
|
||||
.;BetaDigital:10920:HC78M2S0:S19.2E:22000:2047=27:2048=deu@3,2049=eng@3:0:9C4,98C:57:133:15:0
|
||||
.;SKY:10920:HC78M2S0:S19.2E:22000:1023=27:1024=deu@3:0:1837,9C4,98C,1867:38:133:15:0
|
||||
RTL Living;CBC:11082:HC34M5O20P0S1:S19.2E:22000:700=27:710=deu@3,711=qaa@3:0:9C4,98C,98D:11971:1:1041:0
|
||||
Boomerang;SKY:11875:HC34M5O35P0S1:S19.2E:27500:4351=27:4352=deu@3,4353=eng@3:0:98C,9C4,98D:403:133:14:0
|
||||
Cartoon Network,Cartoon Net;SKY:11875:HC34M5O35P0S1:S19.2E:27500:4607=27:4608=deu@3,4609=eng@3:0:98C,9C4,98D:404:133:14:0
|
||||
Nicktoons (S);MTV Networks Europe:11973:VC34M2S0:S19.2E:27500:4121=2:4122=@4:0:500:28682:1:1078:0
|
||||
Beate-Uhse.TV,BeateU;SKY:11719:HC910M2O35P0S1:S19.2E:27500:2303=27:2304=deu@3:0:9C4,98C,9AF,98D:21:133:3:0
|
||||
:Sky Bundesliga HD
|
||||
Sky Sport Bundesliga 1 HD,Sky Buli 1 HD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:255=27:0;258=qab@106,259=qab@106,260=qac@106:32;33=deu:9C4,98C,9AF,98D:105:133:12:0
|
||||
Sky Sport Bundesliga 2 HD,Sky Buli 2 HD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:2047=27:0;2050=qab@106,2051=qab@106:32:9C4,98C,9AF,98D:267:133:6:0
|
||||
Sky Sport Bundesliga 3 HD,Sky Buli 3 HD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:2047=27:0;2050=qab@106,2051=qab@106,2052=qac@106:32:98C,9C4,9AF,98D:277:133:13:0
|
||||
Sky Sport Bundesliga 4 HD,Sky Buli 4 HD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:2047=27:0;2050=qab@106,2051=qab@106,2052=qac@106:32:9C4,98C,9AF,98D:287:133:12:0
|
||||
Sky Sport Bundesliga 5 HD,Sky Buli 5 HD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:2047=27:0;2050=qab@106,2051=qab@106,2052=qac@106:32:98C,9C4,9AF,98D:297:133:11:0
|
||||
Sky Sport Bundesliga 6 HD,Sky Buli 6 HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:2047=27:0;2050=qab@106,2051=qab@106,2052=qac@106:32:98C,9C4,98D:307:133:8:0
|
||||
Sky Sport Bundesliga 7 HD,Sky Buli 7 HD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:1791=27:0;1794=qab@106,1795=qab@106,1796=qac@106:33:98C,9C4:317:133:9:0
|
||||
Sky Sport Bundesliga 8 HD,Sky Buli 8 HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:2559=27:0;2562=deu@106,2563=deu@106,2564=deu@106:0:9C4,98C:327:133:14:0
|
||||
Sky Sport Bundesliga 9 HD,Sky Buli 9 HD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:2559=27:0;2562=qab@106,2563=qab@106,2564=qac@106:32:98C,9C4:337:133:10:0
|
||||
Sky Sport Bundesliga 10 HD,Sky Buli 10 HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:2047=27:0;2050=deu@106,2051=deu@106,2052=deu@106:0:9C4,98C:257:133:14:0
|
||||
Sky Sport Fanzone HD,Fanzone HD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:1279=27:0:0:98C,9C4:102:133:10:0
|
||||
:Sky Sport HD
|
||||
Sky Sport News HD,SportNewsHD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:1023=27:0;1027=deu@106:0:0:108:133:12:0
|
||||
Sky Sport 1 HD,Sky Sport 1 HD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:767=27:0;770=qae@106,771=qaf@106:32:98C,9C4,9AF,98D:129:133:6:0
|
||||
Sky Sport 2 HD,Sky Sport 2 HD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:1023=27:0;1026=qae@106,1027=qaf@106,1028=qtz@106:32:98C,9C4,9AF,98D:114:133:13:0
|
||||
Sky Sport 3 HD,Sky Sport 3 HD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106,2308=qtz@106:32:98C,9C4,9AF,98D:268:133:6:0
|
||||
Sky Sport 4 HD,Sky Sport 4 HD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106,2308=qtz@106:32:98C,9C4,9AF:278:133:13:0
|
||||
Sky Sport 5 HD,Sky Sport 5 HD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106:261:9C4,98C,9AF:288:133:12:0
|
||||
Sky Sport 6 HD,Sky Sport 6 HD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106,2308=qtz@106:32:98C,9C4,9AF,98D:298:133:11:0
|
||||
Sky Sport 7 HD,Sky Sport 7 HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106,2308=qtz@106:32:98C,9C4,98D:308:133:8:0
|
||||
Sky Sport 8 HD,Sky Sport 8 HD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:3071=27:0;3074=qae@106,3075=qaf@106,3076=qtz@106:32:98C,9C4,98D:318:133:9:0
|
||||
Sky Sport 9 HD,Sky Sport 9 HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:2815=27:0;2818=deu@106,2819=deu@106:32:98C,9C4:328:133:14:0
|
||||
Sky Sport 10 HD,Sky Sport 10HD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:2815=27:0;2818=qae@106,2819=qaf@106,2820=qtz@106:32:98C,9C4,98D:338:133:10:0
|
||||
Sky Sport 11 HD,Sky Sport 11HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106,2308=qtz@106:32:98C,9C4,98D:258:133:14:0
|
||||
Eurosport 1 HD,Eurosp1 HD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106:0:98C,9C4,9AF,98D:132:133:11:0
|
||||
Eurosport 2 HD,Eurosp2HD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:1279=27:0;1283=deu@106,1284=eng@106:0:9C4,98C,98D:109:133:9:0
|
||||
Sport1+ HD,Sport1+HD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:1279=27:0;1283=deu@106:0:98C,9C4,98D,9AF:122:133:11:0
|
||||
Sport1 US HD,Sport1USHD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:511=27:0;515=deu@106:32:98C,9C4:119:133:10:0
|
||||
Sky Sport Austria HD,SportAutHD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:1023=27:0;1027=deu@106:0:9C4,98C,98D:143:133:9:0
|
||||
:@1000 Neue Kanaele
|
||||
|
13
channels.h
13
channels.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: channels.h 4.2 2015/08/17 09:39:48 kls Exp $
|
||||
* $Id: channels.h 5.3 2024/03/02 16:21:16 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CHANNELS_H
|
||||
@ -87,6 +87,7 @@ class cChannels;
|
||||
class cChannel : public cListObject {
|
||||
friend class cSchedules;
|
||||
friend class cMenuEditChannel;
|
||||
friend class cMenuSetupMisc;
|
||||
friend class cDvbSourceParam;
|
||||
private:
|
||||
static cString ToText(const cChannel *Channel);
|
||||
@ -96,6 +97,7 @@ private:
|
||||
char *portalName;
|
||||
int __BeginData__;
|
||||
int frequency; // MHz
|
||||
mutable int transponder; // cached value
|
||||
int source;
|
||||
int srate;
|
||||
int vpid;
|
||||
@ -105,7 +107,7 @@ private:
|
||||
int atypes[MAXAPIDS + 1]; // list is zero-terminated
|
||||
char alangs[MAXAPIDS][MAXLANGCODE2];
|
||||
int dpids[MAXDPIDS + 1]; // list is zero-terminated
|
||||
int dtypes[MAXAPIDS + 1]; // list is zero-terminated
|
||||
int dtypes[MAXDPIDS + 1]; // list is zero-terminated
|
||||
char dlangs[MAXDPIDS][MAXLANGCODE2];
|
||||
int spids[MAXSPIDS + 1]; // list is zero-terminated
|
||||
char slangs[MAXSPIDS][MAXLANGCODE2];
|
||||
@ -122,8 +124,8 @@ private:
|
||||
int number; // Sequence number assigned on load
|
||||
bool groupSep;
|
||||
int __EndData__;
|
||||
mutable cString nameSource;
|
||||
mutable cString shortNameSource;
|
||||
cString nameSource;
|
||||
cString shortNameSource;
|
||||
cString parameters;
|
||||
mutable int modification;
|
||||
time_t seen; // When this channel was last seen in the SDT of its transponder
|
||||
@ -131,6 +133,7 @@ private:
|
||||
cLinkChannels *linkChannels;
|
||||
cChannel *refChannel;
|
||||
cString TransponderDataToString(void) const;
|
||||
void UpdateNameSource(void);
|
||||
public:
|
||||
cChannel(void);
|
||||
cChannel(const cChannel &Channel);
|
||||
@ -177,6 +180,7 @@ public:
|
||||
void SetNumber(int Number) { number = Number; }
|
||||
bool GroupSep(void) const { return groupSep; }
|
||||
const char *Parameters(void) const { return parameters; }
|
||||
const cSchedule *Schedule(void) const { return schedule; }
|
||||
const cLinkChannels* LinkChannels(void) const { return linkChannels; }
|
||||
const cChannel *RefChannel(void) const { return refChannel; }
|
||||
bool IsAtsc(void) const { return cSource::IsAtsc(source); }
|
||||
@ -229,6 +233,7 @@ public:
|
||||
int GetNextNormal(int Idx) const; ///< Get next normal channel (not group)
|
||||
int GetPrevNormal(int Idx) const; ///< Get previous normal channel (not group)
|
||||
void ReNumber(void); ///< Recalculate 'number' based on channel type
|
||||
bool MoveNeedsDecrement(cChannel *From, cChannel *To); // Detect special case when moving a channel (closely related to Renumber())
|
||||
void Del(cChannel *Channel); ///< Delete the given Channel from the list
|
||||
const cChannel *GetByNumber(int Number, int SkipGap = 0) const;
|
||||
cChannel *GetByNumber(int Number, int SkipGap = 0) { return const_cast<cChannel *>(static_cast<const cChannels *>(this)->GetByNumber(Number, SkipGap)); }
|
||||
|
231
ci.h
231
ci.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: ci.h 3.11 2015/01/31 14:36:41 kls Exp $
|
||||
* $Id: ci.h 4.14 2019/05/28 14:58:08 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CI_H
|
||||
@ -13,13 +13,107 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "channels.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "thread.h"
|
||||
#include "tools.h"
|
||||
|
||||
#define MAX_CAM_SLOTS_PER_ADAPTER 8 // maximum possible value is 255
|
||||
#define MAX_CAM_SLOTS_PER_ADAPTER 16 // maximum possible value is 255 (same value as MAXDEVICES!)
|
||||
#define MAX_CONNECTIONS_PER_CAM_SLOT 8 // maximum possible value is 254
|
||||
#define CAM_READ_TIMEOUT 50 // ms
|
||||
|
||||
class cCiTransportConnection;
|
||||
class cCamSlot;
|
||||
|
||||
// VDR's Common Interface functions implement only the features that are absolutely
|
||||
// necessary to control a CAM. If a plugin wants to implement additional functionality
|
||||
// (i.e. "resources"), it can do so by deriving from cCiResourceHandler, cCiSession
|
||||
// and (if necessary) from cCiApplicationInformation.
|
||||
|
||||
class cCiSession {
|
||||
private:
|
||||
uint16_t sessionId;
|
||||
uint32_t resourceId;
|
||||
cCiTransportConnection *tc;
|
||||
protected:
|
||||
void SetTsPostProcessor(void);
|
||||
///< If this cCiSession implements the TsPostProcess() function, it shall call
|
||||
///< SetTsPostProcessor() to register itself as the TS post processor.
|
||||
void SetResourceId(uint32_t Id);
|
||||
///< If this is a class that has been derived from an existing cCiSession class,
|
||||
///< but implements a different resource id, it shall call SetResourceId() with
|
||||
///< that Id.
|
||||
int GetTag(int &Length, const uint8_t **Data);
|
||||
const uint8_t *GetData(const uint8_t *Data, int &Length);
|
||||
void SendData(int Tag, int Length = 0, const uint8_t *Data = NULL);
|
||||
cCiTransportConnection *Tc(void) { return tc; }
|
||||
public:
|
||||
cCiSession(uint16_t SessionId, uint32_t ResourceId, cCiTransportConnection *Tc);
|
||||
virtual ~cCiSession();
|
||||
uint16_t SessionId(void) { return sessionId; }
|
||||
uint32_t ResourceId(void) { return resourceId; }
|
||||
cCamSlot *CamSlot(void);
|
||||
virtual bool HasUserIO(void) { return false; }
|
||||
virtual void Process(int Length = 0, const uint8_t *Data = NULL);
|
||||
virtual bool TsPostProcess(uint8_t *TsPacket) { return false; }
|
||||
///< If this cCiSession needs to do additional processing on TS packets (after
|
||||
///< the CAM has done the decryption), it shall implement TsPostProcess() and
|
||||
///< do whatever operations are necessary on the given TsPacket. This function
|
||||
///< is called once for each TS packet, and any and all operations must be
|
||||
///< finished upon return.
|
||||
///< A derived cCiSession that implements this function must call
|
||||
///< SetTsPostProcessor() to make it actually get called.
|
||||
///< Returns true if the TsPacket was in any way modified.
|
||||
};
|
||||
|
||||
class cCiApplicationInformation : public cCiSession {
|
||||
protected:
|
||||
int state;
|
||||
uint8_t applicationType;
|
||||
uint16_t applicationManufacturer;
|
||||
uint16_t manufacturerCode;
|
||||
char *menuString;
|
||||
public:
|
||||
cCiApplicationInformation(uint16_t SessionId, cCiTransportConnection *Tc);
|
||||
virtual ~cCiApplicationInformation();
|
||||
virtual void Process(int Length = 0, const uint8_t *Data = NULL);
|
||||
bool EnterMenu(void);
|
||||
const char *GetMenuString(void) { return menuString; }
|
||||
};
|
||||
|
||||
class cCiResourceHandler : public cListObject {
|
||||
public:
|
||||
cCiResourceHandler(void);
|
||||
///< Creates a new resource handler, through which the available resources
|
||||
///< can be provides. A resource handler shall be allocated on the heap and
|
||||
///< registered with the global CiResourceHandlers, as in
|
||||
///< CiResourceHandlers.Register(new cMyResourceHandler);
|
||||
///< It will be automatically deleted at the end of the program.
|
||||
virtual ~cCiResourceHandler();
|
||||
virtual const uint32_t *ResourceIds(void) const = 0;
|
||||
///< Returns a pointer to an array of resource identifiers, where the
|
||||
///< last value is zero.
|
||||
virtual cCiSession *GetNewCiSession(uint32_t ResourceId, uint16_t SessionId, cCiTransportConnection *Tc) = 0;
|
||||
///< Returns a new cCiSession, according to the given ResourceId.
|
||||
};
|
||||
|
||||
class cCiResourceHandlers : public cList<cCiResourceHandler> {
|
||||
private:
|
||||
cVector<uint32_t> resourceIds;
|
||||
public:
|
||||
cCiResourceHandlers(void);
|
||||
///< Creates the default list of resourceIds.
|
||||
void Register(cCiResourceHandler *ResourceHandler);
|
||||
///< Adds the given ResourceHandler to the list of resource handlers and
|
||||
///< appends its ResourceIds to the global resourceIds.
|
||||
///< A plugin that implements additional CAM capabilities must call
|
||||
///< this function to register its resources.
|
||||
const uint32_t *Ids(void) { return &resourceIds[0]; }
|
||||
int NumIds(void) { return resourceIds.Size(); }
|
||||
cCiSession *GetNewCiSession(uint32_t ResourceId, uint16_t SessionId, cCiTransportConnection *Tc);
|
||||
};
|
||||
|
||||
extern cCiResourceHandlers CiResourceHandlers;
|
||||
|
||||
class cCiMMI;
|
||||
|
||||
class cCiMenu {
|
||||
@ -72,7 +166,6 @@ public:
|
||||
};
|
||||
|
||||
class cDevice;
|
||||
class cCamSlot;
|
||||
|
||||
enum eModuleStatus { msNone, msReset, msPresent, msReady };
|
||||
|
||||
@ -124,14 +217,28 @@ class cCiSession;
|
||||
class cCiCaProgramData;
|
||||
class cCaPidReceiver;
|
||||
class cCaActivationReceiver;
|
||||
class cMtdHandler;
|
||||
class cMtdMapper;
|
||||
class cMtdCamSlot;
|
||||
class cCiCaPmt;
|
||||
|
||||
struct cCiCaPmtList {
|
||||
cVector<cCiCaPmt *> caPmts;
|
||||
~cCiCaPmtList();
|
||||
cCiCaPmt *Add(uint8_t CmdId, int Source, int Transponder, int ProgramNumber, const int *CaSystemIds);
|
||||
void Del(cCiCaPmt *CaPmt);
|
||||
};
|
||||
|
||||
class cCamSlot : public cListObject {
|
||||
friend class cCiAdapter;
|
||||
friend class cCiTransportConnection;
|
||||
friend class cCiConditionalAccessSupport;
|
||||
friend class cMtdCamSlot;
|
||||
private:
|
||||
cMutex mutex;
|
||||
cCondVar processed;
|
||||
cCiAdapter *ciAdapter;
|
||||
cCamSlot *masterSlot;
|
||||
cDevice *assignedDevice;
|
||||
cCaPidReceiver *caPidReceiver;
|
||||
cCaActivationReceiver *caActivationReceiver;
|
||||
@ -145,23 +252,71 @@ private:
|
||||
int source;
|
||||
int transponder;
|
||||
cList<cCiCaProgramData> caProgramList;
|
||||
const int *GetCaSystemIds(void);
|
||||
void SendCaPmt(uint8_t CmdId);
|
||||
bool mtdAvailable;
|
||||
cMtdHandler *mtdHandler;
|
||||
void KeepSharedCaPids(int ProgramNumber, const int *CaSystemIds, int *CaPids);
|
||||
void NewConnection(void);
|
||||
void DeleteAllConnections(void);
|
||||
void Process(cTPDU *TPDU = NULL);
|
||||
void Write(cTPDU *TPDU);
|
||||
cCiSession *GetSessionByResourceId(uint32_t ResourceId);
|
||||
void MtdActivate(bool On);
|
||||
///< Activates (On == true) or deactivates (On == false) MTD.
|
||||
protected:
|
||||
virtual const int *GetCaSystemIds(void);
|
||||
virtual void SendCaPmt(uint8_t CmdId);
|
||||
virtual bool RepliesToQuery(void);
|
||||
///< Returns true if the CAM in this slot replies to queries and thus
|
||||
///< supports MCD ("Multi Channel Decryption").
|
||||
void BuildCaPmts(uint8_t CmdId, cCiCaPmtList &CaPmtList, cMtdMapper *MtdMapper = NULL);
|
||||
///< Generates all CA_PMTs with the given CmdId and stores them in the given CaPmtList.
|
||||
///< If MtdMapper is given, all SIDs and PIDs will be mapped accordingly.
|
||||
void SendCaPmts(cCiCaPmtList &CaPmtList);
|
||||
///< Sends the given list of CA_PMTs to the CAM.
|
||||
void MtdEnable(void);
|
||||
///< Enables MTD support for this CAM. Note that actual MTD operation also
|
||||
///< requires a CAM that supports MCD ("Multi Channel Decryption").
|
||||
int MtdPutData(uchar *Data, int Count);
|
||||
///< Sends at most Count bytes of the given Data to the individual MTD CAM slots
|
||||
///< that are using this CAM. Data must point to the beginning of a TS packet.
|
||||
///< Returns the number of bytes actually processed.
|
||||
public:
|
||||
cCamSlot(cCiAdapter *CiAdapter, bool WantsTsData = false);
|
||||
bool McdAvailable(void) { return RepliesToQuery(); }
|
||||
///< Returns true if this CAM supports MCD ("Multi Channel Decyption").
|
||||
bool MtdAvailable(void) { return mtdAvailable; }
|
||||
///< Returns true if this CAM supports MTD ("Multi Transponder Decryption").
|
||||
bool MtdActive(void) { return mtdHandler != NULL; }
|
||||
///< Returns true if MTD is currently active.
|
||||
public:
|
||||
cCamSlot(cCiAdapter *CiAdapter, bool WantsTsData = false, cCamSlot *MasterSlot = NULL);
|
||||
///< Creates a new CAM slot for the given CiAdapter.
|
||||
///< The CiAdapter will take care of deleting the CAM slot,
|
||||
///< so the caller must not delete it!
|
||||
///< If WantsTsData is true, the device this CAM slot is assigned to will
|
||||
///< call the Decrypt() function of this CAM slot, presenting it the complete
|
||||
///< TS data stream of the encrypted programme, including the CA pids.
|
||||
///< If this CAM slot is basically the same as an other one, MasterSlot can
|
||||
///< be given to indicate this. This can be used for instance for CAM slots
|
||||
///< that can do MTD ("Multi Transponder Decryption"), where the first cCamSlot
|
||||
///< is created without giving a MasterSlot, and all others are given the first
|
||||
///< one as their MasterSlot. This can speed up the search for a suitable CAM
|
||||
///< when tuning to an encrypted channel, and it also makes the Setup/CAM menu
|
||||
///< clearer because only the master CAM slots will be shown there.
|
||||
virtual ~cCamSlot();
|
||||
bool Assign(cDevice *Device, bool Query = false);
|
||||
bool IsMasterSlot(void) { return !masterSlot; }
|
||||
///< Returns true if this CAM slot itself is a master slot (which means that
|
||||
///< it doesn't have a pointer to another CAM slot that's its master).
|
||||
cCamSlot *MasterSlot(void) { return masterSlot ? masterSlot : this; }
|
||||
///< Returns this CAM slot's master slot, or a pointer to itself if it is a
|
||||
///< master slot.
|
||||
cCamSlot *MtdSpawn(void);
|
||||
///< If this CAM slot can do MTD ("Multi Transponder Decryption"),
|
||||
///< a call to this function returns a cMtdCamSlot with this CAM slot
|
||||
///< as its master. Otherwise a pointer to this object is returned, which
|
||||
///< means that MTD is not supported.
|
||||
void TriggerResendPmt(void) { resendPmt = true; }
|
||||
///< Tells this CAM slot to resend the list of CA_PMTs to the CAM.
|
||||
virtual bool Assign(cDevice *Device, bool Query = false);
|
||||
///< Assigns this CAM slot to the given Device, if this is possible.
|
||||
///< If Query is 'true', the CI adapter of this slot only checks whether
|
||||
///< it can be assigned to the Device, but doesn't actually assign itself to it.
|
||||
@ -170,8 +325,16 @@ public:
|
||||
///< device it was previously assigned to. The value of Query
|
||||
///< is ignored in that case, and this function always returns
|
||||
///< 'true'.
|
||||
///< If a derived class reimplements this function, it can return 'false'
|
||||
///< if this CAM can't be assigned to the given Device. If the CAM can be
|
||||
///< assigned to the Device, or if Device is NULL, it must call the base
|
||||
///< class function.
|
||||
cDevice *Device(void) { return assignedDevice; }
|
||||
///< Returns the device this CAM slot is currently assigned to.
|
||||
bool Devices(cVector<int> &DeviceNumbers);
|
||||
///< Adds the numbers of any devices that currently use this CAM to
|
||||
///< the given DeviceNumbers. This can be more than one in case of MTD.
|
||||
///< Returns true if the array is not empty.
|
||||
bool WantsTsData(void) const { return caPidReceiver != NULL; }
|
||||
///< Returns true if this CAM slot wants to receive the TS data through
|
||||
///< its Decrypt() function.
|
||||
@ -181,6 +344,9 @@ public:
|
||||
int SlotNumber(void) { return slotNumber; }
|
||||
///< Returns the number of this CAM slot within the whole system.
|
||||
///< The first slot has the number 1.
|
||||
int MasterSlotNumber(void) { return masterSlot ? masterSlot->SlotNumber() : slotNumber; }
|
||||
///< Returns the number of this CAM's master slot within the whole system.
|
||||
///< The first slot has the number 1.
|
||||
virtual bool Reset(void);
|
||||
///< Resets the CAM in this slot.
|
||||
///< Returns true if the operation was successful.
|
||||
@ -237,11 +403,11 @@ public:
|
||||
///< call to AddPid()) to Active. A later call to StartDecrypting() will
|
||||
///< send the full list of currently active CA_PMT entries to the CAM.
|
||||
virtual void AddChannel(const cChannel *Channel);
|
||||
///< Adds all PIDs if the given Channel to the current list of PIDs.
|
||||
///< Adds all PIDs of the given Channel to the current list of PIDs.
|
||||
///< If the source or transponder of the channel are different than
|
||||
///< what was given in a previous call to AddChannel(), any previously
|
||||
///< added PIDs will be cleared.
|
||||
virtual bool CanDecrypt(const cChannel *Channel);
|
||||
virtual bool CanDecrypt(const cChannel *Channel, cMtdMapper *MtdMapper = NULL);
|
||||
///< Returns true if there is a CAM in this slot that is able to decrypt
|
||||
///< the given Channel (or at least claims to be able to do so).
|
||||
///< Since the QUERY/REPLY mechanism for CAMs is pretty unreliable (some
|
||||
@ -252,11 +418,18 @@ public:
|
||||
///< to the initial QUERY will perform this check at all. CAMs that never
|
||||
///< replied to the initial QUERY are assumed not to be able to handle
|
||||
///< more than one channel at a time.
|
||||
///< If MtdMapper is given, all SIDs and PIDs will be mapped accordingly.
|
||||
virtual void StartDecrypting(void);
|
||||
///< Triggers sending all currently active CA_PMT entries to the CAM,
|
||||
///< so that it will start decrypting.
|
||||
///< Sends all CA_PMT entries to the CAM that have been modified since the
|
||||
///< last call to this function. This includes CA_PMTs that have been
|
||||
///< added or activated, as well as ones that have been deactivated.
|
||||
///< StartDecrypting() will be called whenever a PID is activated or
|
||||
///< deactivated.
|
||||
virtual void StopDecrypting(void);
|
||||
///< Clears the list of CA_PMT entries and tells the CAM to stop decrypting.
|
||||
///< Note that this function is only called when there are no more PIDs for
|
||||
///< the CAM to decrypt. There is no symmetry between StartDecrypting() and
|
||||
///< StopDecrypting().
|
||||
virtual bool IsDecrypting(void);
|
||||
///< Returns true if the CAM in this slot is currently used for decrypting.
|
||||
virtual uchar *Decrypt(uchar *Data, int &Count);
|
||||
@ -265,7 +438,12 @@ public:
|
||||
///< in hardware, it can implement this function to be given access
|
||||
///< to the data in the device's TS buffer. Data points to a buffer
|
||||
///< of Count bytes of TS data. The first byte in Data is guaranteed
|
||||
///< to be a TS_SYNC_BYTE.
|
||||
///< to be a TS_SYNC_BYTE, and Count is at least TS_SIZE.
|
||||
///< Note that Decrypt() may be called with Data == NULL! This is necessary
|
||||
///< to allow CAMs that copy the incoming data into a separate buffer to
|
||||
///< return previously received and decrypted TS packets. If Data is NULL,
|
||||
///< Count is 0 and must not be modified, and the return value shall point to the
|
||||
///< next available decrypted TS packet (if any).
|
||||
///< There are three possible ways a CAM can handle decryption:
|
||||
///< 1. If the full TS data is physically routed through the CAM in hardware,
|
||||
///< there is no need to reimplement this function.
|
||||
@ -287,14 +465,36 @@ public:
|
||||
///< the CAM's control). If no decrypted TS packet is currently available, NULL
|
||||
///< shall be returned. If no data from Data can currently be processed, Count
|
||||
///< shall be set to 0 and the same Data pointer will be offered in the next
|
||||
///< call to Decrypt().
|
||||
///< call to Decrypt(). See mtd.h for further requirements if this CAM can
|
||||
///< do MTD ("Multi Transponder Decryption").
|
||||
///< A derived class that implements this function will also need
|
||||
///< to set the WantsTsData parameter in the call to the base class
|
||||
///< constructor to true in order to receive the TS data.
|
||||
virtual bool TsPostProcess(uchar *Data);
|
||||
///< If there is a cCiSession that needs to do additional processing on TS packets
|
||||
///< (after the CAM has done the decryption), this function will call its
|
||||
///< TsPostProcess() function to have it do whatever operations are necessary on
|
||||
///< the given TsPacket.
|
||||
///< Returns true if the TsPacket was in any way modified.
|
||||
virtual bool Inject(uchar *Data, int Count);
|
||||
///< Sends all Count bytes of the given Data to the CAM, and returns true
|
||||
///< if this was possible. If the data can't be sent to the CAM completely,
|
||||
///< nothing shall be sent and the return value shall be false.
|
||||
///< No decrypted packet is returned by this function.
|
||||
///< Data is guaranteed to point to one or more complete TS packets.
|
||||
virtual void InjectEit(int Sid);
|
||||
///< Injects a generated EIT with a "present event" for the given Sid into
|
||||
///< the TS data stream sent to the CAM. This only applies to CAM slots that
|
||||
///< have WantsTsData set to true in their constructor.
|
||||
///< The default implementation sends an EIT with the minimum event
|
||||
///< necessary to disable the CAMs parental rating prompt.
|
||||
};
|
||||
|
||||
class cCamSlots : public cList<cCamSlot> {
|
||||
public:
|
||||
int NumReadyMasterSlots(void);
|
||||
///< Returns the number of master CAM slots in the system that are ready
|
||||
///< to decrypt.
|
||||
bool WaitForAllCamSlotsReady(int Timeout = 0);
|
||||
///< Waits until all CAM slots have become ready, or the given Timeout
|
||||
///< (seconds) has expired. While waiting, the Ready() function of each
|
||||
@ -310,6 +510,7 @@ class cChannelCamRelation;
|
||||
class cChannelCamRelations : public cList<cChannelCamRelation> {
|
||||
private:
|
||||
cMutex mutex;
|
||||
cString fileName;
|
||||
cChannelCamRelation *GetEntry(tChannelID ChannelID);
|
||||
cChannelCamRelation *AddEntry(tChannelID ChannelID);
|
||||
time_t lastCleanup;
|
||||
@ -323,8 +524,12 @@ public:
|
||||
void SetDecrypt(tChannelID ChannelID, int CamSlotNumber);
|
||||
void ClrChecked(tChannelID ChannelID, int CamSlotNumber);
|
||||
void ClrDecrypt(tChannelID ChannelID, int CamSlotNumber);
|
||||
void Load(const char *FileName);
|
||||
void Save(void);
|
||||
};
|
||||
|
||||
extern cChannelCamRelations ChannelCamRelations;
|
||||
|
||||
bool CamResponsesLoad(const char *FileName, bool AllowComments = false, bool MustExist = false);
|
||||
|
||||
#endif //__CI_H
|
||||
|
17
config.c
17
config.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: config.c 4.4 2015/09/13 11:09:44 kls Exp $
|
||||
* $Id: config.c 5.1 2024/03/04 21:13:58 kls Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -409,6 +409,8 @@ cSetup::cSetup(void)
|
||||
SubtitleBgTransparency = 0;
|
||||
EPGLanguages[0] = -1;
|
||||
EPGScanTimeout = 5;
|
||||
EPGScanMaxChannel = 0;
|
||||
EPGPauseAfterScan = 0;
|
||||
EPGBugfixLevel = 3;
|
||||
EPGLinger = 0;
|
||||
SVDRPTimeout = 300;
|
||||
@ -432,6 +434,7 @@ cSetup::cSetup(void)
|
||||
FoldersInTimerMenu = 1;
|
||||
AlwaysSortFoldersFirst = 1;
|
||||
DefaultSortModeRec = rsmTime;
|
||||
RecSortingDirection = rsdAscending;
|
||||
NumberKeysForChars = 1;
|
||||
ColorKey0 = 0;
|
||||
ColorKey1 = 1;
|
||||
@ -636,12 +639,14 @@ bool cSetup::Parse(const char *Name, const char *Value)
|
||||
else if (!strcasecmp(Name, "SubtitleBgTransparency")) SubtitleBgTransparency = atoi(Value);
|
||||
else if (!strcasecmp(Name, "EPGLanguages")) return ParseLanguages(Value, EPGLanguages);
|
||||
else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value);
|
||||
else if (!strcasecmp(Name, "EPGScanMaxChannel")) EPGScanMaxChannel = atoi(Value);
|
||||
else if (!strcasecmp(Name, "EPGPauseAfterScan")) EPGPauseAfterScan = atoi(Value);
|
||||
else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value);
|
||||
else if (!strcasecmp(Name, "EPGLinger")) EPGLinger = atoi(Value);
|
||||
else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value);
|
||||
else if (!strcasecmp(Name, "SVDRPPeering")) SVDRPPeering = atoi(Value);
|
||||
else if (!strcasecmp(Name, "SVDRPHostName")) strn0cpy(SVDRPHostName, Value, sizeof(SVDRPHostName));
|
||||
else if (!strcasecmp(Name, "SVDRPdefaultHost")) strn0cpy(SVDRPDefaultHost, Value, sizeof(SVDRPDefaultHost));
|
||||
else if (!strcasecmp(Name, "SVDRPHostName")) { if (*Value) strn0cpy(SVDRPHostName, Value, sizeof(SVDRPHostName)); }
|
||||
else if (!strcasecmp(Name, "SVDRPDefaultHost")) strn0cpy(SVDRPDefaultHost, Value, sizeof(SVDRPDefaultHost));
|
||||
else if (!strcasecmp(Name, "ZapTimeout")) ZapTimeout = atoi(Value);
|
||||
else if (!strcasecmp(Name, "ChannelEntryTimeout")) ChannelEntryTimeout= atoi(Value);
|
||||
else if (!strcasecmp(Name, "RcRepeatDelay")) RcRepeatDelay = atoi(Value);
|
||||
@ -658,6 +663,7 @@ bool cSetup::Parse(const char *Name, const char *Value)
|
||||
else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value);
|
||||
else if (!strcasecmp(Name, "FoldersInTimerMenu")) FoldersInTimerMenu = atoi(Value);
|
||||
else if (!strcasecmp(Name, "AlwaysSortFoldersFirst")) AlwaysSortFoldersFirst = atoi(Value);
|
||||
else if (!strcasecmp(Name, "RecSortingDirection")) RecSortingDirection= atoi(Value);
|
||||
else if (!strcasecmp(Name, "DefaultSortModeRec")) DefaultSortModeRec = atoi(Value);
|
||||
else if (!strcasecmp(Name, "NumberKeysForChars")) NumberKeysForChars = atoi(Value);
|
||||
else if (!strcasecmp(Name, "ColorKey0")) ColorKey0 = atoi(Value);
|
||||
@ -767,11 +773,13 @@ bool cSetup::Save(void)
|
||||
Store("SubtitleBgTransparency", SubtitleBgTransparency);
|
||||
StoreLanguages("EPGLanguages", EPGLanguages);
|
||||
Store("EPGScanTimeout", EPGScanTimeout);
|
||||
Store("EPGScanMaxChannel", EPGScanMaxChannel);
|
||||
Store("EPGPauseAfterScan", EPGPauseAfterScan);
|
||||
Store("EPGBugfixLevel", EPGBugfixLevel);
|
||||
Store("EPGLinger", EPGLinger);
|
||||
Store("SVDRPTimeout", SVDRPTimeout);
|
||||
Store("SVDRPPeering", SVDRPPeering);
|
||||
Store("SVDRPHostName", SVDRPHostName);
|
||||
Store("SVDRPHostName", strcmp(SVDRPHostName, GetHostName()) ? SVDRPHostName : "");
|
||||
Store("SVDRPDefaultHost", SVDRPDefaultHost);
|
||||
Store("ZapTimeout", ZapTimeout);
|
||||
Store("ChannelEntryTimeout",ChannelEntryTimeout);
|
||||
@ -789,6 +797,7 @@ bool cSetup::Save(void)
|
||||
Store("RecordingDirs", RecordingDirs);
|
||||
Store("FoldersInTimerMenu", FoldersInTimerMenu);
|
||||
Store("AlwaysSortFoldersFirst", AlwaysSortFoldersFirst);
|
||||
Store("RecSortingDirection",RecSortingDirection);
|
||||
Store("DefaultSortModeRec", DefaultSortModeRec);
|
||||
Store("NumberKeysForChars", NumberKeysForChars);
|
||||
Store("ColorKey0", ColorKey0);
|
||||
|
30
config.h
30
config.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: config.h 4.5 2015/09/11 08:07:34 kls Exp $
|
||||
* $Id: config.h 5.26 2025/02/26 10:35:03 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
@ -22,19 +22,21 @@
|
||||
|
||||
// VDR's own version number:
|
||||
|
||||
#define VDRVERSION "2.3.1"
|
||||
#define VDRVERSNUM 20301 // Version * 10000 + Major * 100 + Minor
|
||||
#define VDRVERSION "2.7.4"
|
||||
#define VDRVERSNUM 20704 // Version * 10000 + Major * 100 + Minor
|
||||
|
||||
// The plugin API's version number:
|
||||
|
||||
#define APIVERSION "2.3.1"
|
||||
#define APIVERSNUM 20301 // Version * 10000 + Major * 100 + Minor
|
||||
#define APIVERSION "6"
|
||||
#define APIVERSNUM 30006
|
||||
|
||||
// When loading plugins, VDR searches them by their APIVERSION, which
|
||||
// may be smaller than VDRVERSION in case there have been no changes to
|
||||
// VDR header files since the last APIVERSION. This allows compiled
|
||||
// When loading plugins, VDR searches files by their APIVERSION, which
|
||||
// is different from VDRVERSION. APIVERSION is a plain number, incremented
|
||||
// only when there are changes to the plugin API. This allows compiled
|
||||
// plugins to work with newer versions of the core VDR as long as no
|
||||
// VDR header files have changed.
|
||||
// interfaces have changed. APIVERSNUM begins with "300.." for backwards
|
||||
// compatibility and can be used in #if preprocessor statements to handle
|
||||
// version dependent code.
|
||||
|
||||
#define MAXPRIORITY 99
|
||||
#define MINPRIORITY (-MAXPRIORITY)
|
||||
@ -46,6 +48,13 @@
|
||||
|
||||
#define TIMERMACRO_TITLE "TITLE"
|
||||
#define TIMERMACRO_EPISODE "EPISODE"
|
||||
#define TIMERMACRO_BEFORE "{<}"
|
||||
#define TIMERMACRO_MATCH "{=}"
|
||||
#define TIMERMACRO_AFTER "{>}"
|
||||
|
||||
#define TIMERPATTERN_AVOID "@"
|
||||
#define TIMERPATTERN_BEGIN "^"
|
||||
#define TIMERPATTERN_END "$"
|
||||
|
||||
#define MINOSDWIDTH 480
|
||||
#define MAXOSDWIDTH 1920
|
||||
@ -284,6 +293,8 @@ public:
|
||||
int SubtitleOffset;
|
||||
int SubtitleFgTransparency, SubtitleBgTransparency;
|
||||
int EPGLanguages[I18N_MAX_LANGUAGES + 1];
|
||||
int EPGScanMaxChannel;
|
||||
int EPGPauseAfterScan;
|
||||
int EPGScanTimeout;
|
||||
int EPGBugfixLevel;
|
||||
int EPGLinger;
|
||||
@ -306,6 +317,7 @@ public:
|
||||
int FoldersInTimerMenu;
|
||||
int AlwaysSortFoldersFirst;
|
||||
int DefaultSortModeRec;
|
||||
int RecSortingDirection;
|
||||
int NumberKeysForChars;
|
||||
int ColorKey0, ColorKey1, ColorKey2, ColorKey3;
|
||||
int VideoDisplayFormat;
|
||||
|
73
cutter.c
73
cutter.c
@ -4,12 +4,11 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: cutter.c 4.2 2015/08/09 12:24:28 kls Exp $
|
||||
* $Id: cutter.c 5.4 2025/01/10 13:12:04 kls Exp $
|
||||
*/
|
||||
|
||||
#include "cutter.h"
|
||||
#include "menu.h"
|
||||
#include "recording.h"
|
||||
#include "remux.h"
|
||||
#include "videodir.h"
|
||||
|
||||
@ -232,6 +231,10 @@ private:
|
||||
int numSequences;
|
||||
off_t maxVideoFileSize;
|
||||
off_t fileSize;
|
||||
int frameErrors;
|
||||
time_t lastErrorHandling;
|
||||
cString editedRecordingName;
|
||||
cRecordingInfo *recordingInfo;
|
||||
bool suspensionLogged;
|
||||
int sequence; // cutting sequence
|
||||
int delta; // time between two frames (PTS ticks)
|
||||
@ -246,7 +249,7 @@ private:
|
||||
cPatPmtParser patPmtParser;
|
||||
bool Throttled(void);
|
||||
bool SwitchFile(bool Force = false);
|
||||
bool LoadFrame(int Index, uchar *Buffer, bool &Independent, int &Length);
|
||||
bool LoadFrame(int Index, uchar *Buffer, bool &Independent, int &Length, bool *Errors = NULL, bool *Missing = NULL);
|
||||
bool FramesAreEqual(int Index1, int Index2);
|
||||
void GetPendingPackets(uchar *Buffer, int &Length, int Index);
|
||||
// Gather all non-video TS packets from Index upward that either belong to
|
||||
@ -254,15 +257,16 @@ private:
|
||||
// and add them to the end of the given Data.
|
||||
bool FixFrame(uchar *Data, int &Length, bool Independent, int Index, bool CutIn, bool CutOut);
|
||||
bool ProcessSequence(int LastEndIndex, int BeginIndex, int EndIndex, int NextBeginIndex);
|
||||
void HandleErrors(bool Force = false);
|
||||
protected:
|
||||
virtual void Action(void);
|
||||
public:
|
||||
cCuttingThread(const char *FromFileName, const char *ToFileName);
|
||||
cCuttingThread(const char *FromFileName, const char *ToFileName, cRecordingInfo *RecordingInfo);
|
||||
virtual ~cCuttingThread();
|
||||
const char *Error(void) { return error; }
|
||||
};
|
||||
|
||||
cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
|
||||
cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName, cRecordingInfo *RecordingInfo)
|
||||
:cThread("video cutting", true)
|
||||
{
|
||||
error = NULL;
|
||||
@ -274,6 +278,10 @@ cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
|
||||
framesPerSecond = Recording.FramesPerSecond();
|
||||
suspensionLogged = false;
|
||||
fileSize = 0;
|
||||
frameErrors = 0;
|
||||
lastErrorHandling = 0;
|
||||
editedRecordingName = ToFileName;
|
||||
recordingInfo = RecordingInfo;
|
||||
sequence = 0;
|
||||
delta = int(round(PTSTICKS / framesPerSecond));
|
||||
lastVidPts = -1;
|
||||
@ -294,6 +302,10 @@ cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
|
||||
maxVideoFileSize = MEGABYTE(Setup.MaxVideoFileSize);
|
||||
if (isPesRecording && maxVideoFileSize > MEGABYTE(MAXVIDEOFILESIZEPES))
|
||||
maxVideoFileSize = MEGABYTE(MAXVIDEOFILESIZEPES);
|
||||
if (fromIndex->GetErrors()->Size() > 0) {
|
||||
recordingInfo->SetErrors(0); // the fromIndex has error indicators, so we reset the error count
|
||||
recordingInfo->Write();
|
||||
}
|
||||
Start();
|
||||
}
|
||||
else
|
||||
@ -328,11 +340,11 @@ bool cCuttingThread::Throttled(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cCuttingThread::LoadFrame(int Index, uchar *Buffer, bool &Independent, int &Length)
|
||||
bool cCuttingThread::LoadFrame(int Index, uchar *Buffer, bool &Independent, int &Length, bool *Errors, bool *Missing)
|
||||
{
|
||||
uint16_t FileNumber;
|
||||
off_t FileOffset;
|
||||
if (fromIndex->Get(Index, &FileNumber, &FileOffset, &Independent, &Length)) {
|
||||
if (fromIndex->Get(Index, &FileNumber, &FileOffset, &Independent, &Length, Errors, Missing)) {
|
||||
fromFile = fromFileName->SetOffset(FileNumber, FileOffset);
|
||||
if (fromFile) {
|
||||
fromFile->SetReadAhead(MEGABYTE(20));
|
||||
@ -500,7 +512,7 @@ bool cCuttingThread::FixFrame(uchar *Data, int &Length, bool Independent, int In
|
||||
TsSetContinuityCounter(p, counter[Pid]);
|
||||
}
|
||||
else
|
||||
counter[Pid] = TsGetContinuityCounter(p); // collect initial counters
|
||||
counter[Pid] = TsContinuityCounter(p); // collect initial counters
|
||||
// Adjust PTS:
|
||||
int64_t Pts = TsGetPts(p, TS_SIZE);
|
||||
if (Pts >= 0) {
|
||||
@ -555,7 +567,9 @@ bool cCuttingThread::ProcessSequence(int LastEndIndex, int BeginIndex, int EndIn
|
||||
for (int Index = BeginIndex; Running() && Index < EndIndex; Index++) {
|
||||
bool Independent;
|
||||
int Length;
|
||||
if (LoadFrame(Index, Buffer, Independent, Length)) {
|
||||
bool Errors;
|
||||
bool Missing;
|
||||
if (LoadFrame(Index, Buffer, Independent, Length, &Errors, &Missing)) {
|
||||
// Make sure there is enough disk space:
|
||||
AssertFreeDiskSpace(-1);
|
||||
bool CutIn = !SeamlessBegin && Index == BeginIndex;
|
||||
@ -572,10 +586,12 @@ bool cCuttingThread::ProcessSequence(int LastEndIndex, int BeginIndex, int EndIn
|
||||
return false;
|
||||
}
|
||||
// Write index:
|
||||
if (!DeletedFrame && !toIndex->Write(Independent, toFileName->Number(), fileSize)) {
|
||||
if (!DeletedFrame && !toIndex->Write(Independent, toFileName->Number(), fileSize, Errors, Missing)) {
|
||||
error = "toIndex";
|
||||
return false;
|
||||
}
|
||||
frameErrors += Errors + Missing;
|
||||
HandleErrors();
|
||||
// Write data:
|
||||
if (toFile->Write(Buffer, Length) < 0) {
|
||||
error = "safe_write";
|
||||
@ -596,6 +612,27 @@ bool cCuttingThread::ProcessSequence(int LastEndIndex, int BeginIndex, int EndIn
|
||||
return true;
|
||||
}
|
||||
|
||||
#define ERROR_HANDLING_DELTA 1 // seconds between handling errors
|
||||
|
||||
void cCuttingThread::HandleErrors(bool Force)
|
||||
{
|
||||
if (Force || time(NULL) - lastErrorHandling >= ERROR_HANDLING_DELTA) {
|
||||
if (frameErrors > recordingInfo->Errors()) {
|
||||
recordingInfo->SetErrors(frameErrors);
|
||||
recordingInfo->Write();
|
||||
Force = true;
|
||||
}
|
||||
if (Force) {
|
||||
cStateKey StateKey;
|
||||
if (cRecordings *Recordings = cRecordings::GetRecordingsWrite(StateKey, 1)) {
|
||||
Recordings->UpdateByName(editedRecordingName);
|
||||
StateKey.Remove();
|
||||
}
|
||||
}
|
||||
lastErrorHandling = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void cCuttingThread::Action(void)
|
||||
{
|
||||
if (cMark *BeginMark = fromMarks.GetNextBegin()) {
|
||||
@ -604,6 +641,7 @@ void cCuttingThread::Action(void)
|
||||
if (!fromFile || !toFile)
|
||||
return;
|
||||
int LastEndIndex = -1;
|
||||
HandleErrors(true); // to make sure an initially reset error count is displayed correctly
|
||||
while (BeginMark && Running()) {
|
||||
// Suspend cutting if we have severe throughput problems:
|
||||
if (Throttled()) {
|
||||
@ -634,6 +672,7 @@ void cCuttingThread::Action(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
HandleErrors(true);
|
||||
}
|
||||
else
|
||||
esyslog("no editing marks found!");
|
||||
@ -642,6 +681,7 @@ void cCuttingThread::Action(void)
|
||||
// --- cCutter ---------------------------------------------------------------
|
||||
|
||||
cCutter::cCutter(const char *FileName)
|
||||
:recordingInfo(FileName)
|
||||
{
|
||||
cuttingThread = NULL;
|
||||
error = false;
|
||||
@ -676,10 +716,11 @@ bool cCutter::Start(void)
|
||||
if (strcmp(originalVersionName, editedVersionName) != 0) { // names must be different!
|
||||
cRecordingUserCommand::InvokeCommand(RUC_EDITINGRECORDING, editedVersionName, originalVersionName);
|
||||
if (cVideoDirectory::RemoveVideoFile(editedVersionName) && MakeDirs(editedVersionName, true)) {
|
||||
Recording.WriteInfo(editedVersionName);
|
||||
LOCK_RECORDINGS_WRITE;
|
||||
Recordings->AddByName(editedVersionName, false);
|
||||
cuttingThread = new cCuttingThread(originalVersionName, editedVersionName);
|
||||
recordingInfo.Read();
|
||||
recordingInfo.SetFileName(editedVersionName);
|
||||
recordingInfo.Write();
|
||||
SetRecordingTimerId(editedVersionName, cString::sprintf("%d@%s", 0, Setup.SVDRPHostName));
|
||||
cuttingThread = new cCuttingThread(originalVersionName, editedVersionName, &recordingInfo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -695,6 +736,7 @@ void cCutter::Stop(void)
|
||||
const char *Error = cuttingThread ? cuttingThread->Error() : NULL;
|
||||
delete cuttingThread;
|
||||
cuttingThread = NULL;
|
||||
SetRecordingTimerId(editedVersionName, NULL);
|
||||
if ((Interrupted || Error) && *editedVersionName) {
|
||||
if (Interrupted)
|
||||
isyslog("editing process has been interrupted");
|
||||
@ -702,9 +744,6 @@ void cCutter::Stop(void)
|
||||
esyslog("ERROR: '%s' during editing process", Error);
|
||||
if (cReplayControl::NowReplaying() && strcmp(cReplayControl::NowReplaying(), editedVersionName) == 0)
|
||||
cControl::Shutdown();
|
||||
cVideoDirectory::RemoveVideoFile(editedVersionName);
|
||||
LOCK_RECORDINGS_WRITE;
|
||||
Recordings->DelByName(editedVersionName);
|
||||
}
|
||||
}
|
||||
|
||||
|
4
cutter.h
4
cutter.h
@ -4,12 +4,13 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: cutter.h 3.1 2013/10/05 11:34:55 kls Exp $
|
||||
* $Id: cutter.h 5.1 2024/09/19 20:21:58 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CUTTER_H
|
||||
#define __CUTTER_H
|
||||
|
||||
#include "recording.h"
|
||||
#include "thread.h"
|
||||
#include "tools.h"
|
||||
|
||||
@ -19,6 +20,7 @@ class cCutter {
|
||||
private:
|
||||
cString originalVersionName;
|
||||
cString editedVersionName;
|
||||
cRecordingInfo recordingInfo;
|
||||
cCuttingThread *cuttingThread;
|
||||
bool error;
|
||||
public:
|
||||
|
446
device.c
446
device.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: device.c 4.2 2015/09/05 11:42:17 kls Exp $
|
||||
* $Id: device.c 5.14 2024/07/06 11:19:21 kls Exp $
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
@ -58,6 +58,11 @@ bool cDeviceHook::DeviceProvidesTransponder(const cDevice *Device, const cChanne
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cDeviceHook::DeviceProvidesEIT(const cDevice *Device) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// --- cDevice ---------------------------------------------------------------
|
||||
|
||||
// The minimum number of unknown PS1 packets to consider this a "pre 1.3.19 private stream":
|
||||
@ -75,9 +80,9 @@ cDevice::cDevice(void)
|
||||
:patPmtParser(true)
|
||||
{
|
||||
cardIndex = nextCardIndex++;
|
||||
dsyslog("new device number %d", CardIndex() + 1);
|
||||
dsyslog("new device number %d (card index %d)", numDevices + 1, CardIndex() + 1);
|
||||
|
||||
SetDescription("device %d receiver", CardIndex() + 1);
|
||||
SetDescription("device %d receiver", numDevices + 1);
|
||||
|
||||
mute = false;
|
||||
volume = Setup.CurrentVolume;
|
||||
@ -89,9 +94,10 @@ cDevice::cDevice(void)
|
||||
nitFilter = NULL;
|
||||
|
||||
camSlot = NULL;
|
||||
startScrambleDetection = 0;
|
||||
|
||||
occupiedFrom = 0;
|
||||
occupiedTimeout = 0;
|
||||
occupiedPriority = MINPRIORITY;
|
||||
|
||||
player = NULL;
|
||||
isPlayingVideo = false;
|
||||
@ -121,6 +127,7 @@ cDevice::~cDevice()
|
||||
delete dvbSubtitleConverter;
|
||||
if (this == primaryDevice)
|
||||
primaryDevice = NULL;
|
||||
Cancel(3);
|
||||
}
|
||||
|
||||
bool cDevice::WaitForAllDevicesReady(int Timeout)
|
||||
@ -195,6 +202,7 @@ bool cDevice::SetPrimaryDevice(int n)
|
||||
primaryDevice->MakePrimaryDevice(true);
|
||||
primaryDevice->SetVideoFormat(Setup.VideoFormat);
|
||||
primaryDevice->SetVolumeDevice(Setup.CurrentVolume);
|
||||
Setup.PrimaryDVB = n + 1;
|
||||
return true;
|
||||
}
|
||||
esyslog("ERROR: invalid primary device number: %d", n + 1);
|
||||
@ -229,11 +237,11 @@ static int GetClippedNumProvidedSystems(int AvailableBits, cDevice *Device)
|
||||
int MaxNumProvidedSystems = (1 << AvailableBits) - 1;
|
||||
int NumProvidedSystems = Device->NumProvidedSystems();
|
||||
if (NumProvidedSystems > MaxNumProvidedSystems) {
|
||||
esyslog("ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d delivery systems which should be fixed", Device->CardIndex() + 1, NumProvidedSystems, MaxNumProvidedSystems);
|
||||
esyslog("ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d delivery systems which should be fixed", Device->DeviceNumber() + 1, NumProvidedSystems, MaxNumProvidedSystems);
|
||||
NumProvidedSystems = MaxNumProvidedSystems;
|
||||
}
|
||||
else if (NumProvidedSystems <= 0) {
|
||||
esyslog("ERROR: device %d reported an invalid number (%d) of supported delivery systems - assuming 1", Device->CardIndex() + 1, NumProvidedSystems);
|
||||
esyslog("ERROR: device %d reported an invalid number (%d) of supported delivery systems - assuming 1", Device->DeviceNumber() + 1, NumProvidedSystems);
|
||||
NumProvidedSystems = 1;
|
||||
}
|
||||
return NumProvidedSystems;
|
||||
@ -243,7 +251,7 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
|
||||
{
|
||||
// Collect the current priorities of all CAM slots that can decrypt the channel:
|
||||
int NumCamSlots = CamSlots.Count();
|
||||
int SlotPriority[NumCamSlots];
|
||||
int SlotPriority[NumCamSlots + 1]; // +1 to avoid a zero sized array in case there are no CAM slots
|
||||
int NumUsableSlots = 0;
|
||||
bool InternalCamNeeded = false;
|
||||
if (Channel->Ca() >= CA_ENCRYPTED_MIN) {
|
||||
@ -251,8 +259,8 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
|
||||
SlotPriority[CamSlot->Index()] = MAXPRIORITY + 1; // assumes it can't be used
|
||||
if (CamSlot->ModuleStatus() == msReady) {
|
||||
if (CamSlot->ProvidesCa(Channel->Caids())) {
|
||||
if (!ChannelCamRelations.CamChecked(Channel->GetChannelID(), CamSlot->SlotNumber())) {
|
||||
SlotPriority[CamSlot->Index()] = CamSlot->Priority();
|
||||
if (!ChannelCamRelations.CamChecked(Channel->GetChannelID(), CamSlot->MasterSlotNumber())) {
|
||||
SlotPriority[CamSlot->Index()] = CamSlot->MtdActive() ? IDLEPRIORITY : CamSlot->Priority(); // we don't need to take the priority into account here for MTD CAM slots, because they can be used with several devices in parallel
|
||||
NumUsableSlots++;
|
||||
}
|
||||
}
|
||||
@ -271,17 +279,26 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
|
||||
if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY)
|
||||
continue; // there is no CAM available in this slot
|
||||
for (int i = 0; i < numDevices; i++) {
|
||||
if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->CardIndex() + 1)
|
||||
if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->DeviceNumber() + 1)
|
||||
continue; // a specific card was requested, but not this one
|
||||
bool HasInternalCam = device[i]->HasInternalCam();
|
||||
if (InternalCamNeeded && !HasInternalCam)
|
||||
continue; // no CAM is able to decrypt this channel and the device uses vdr handled CAMs
|
||||
if (NumUsableSlots && !HasInternalCam && !CamSlots.Get(j)->Assign(device[i], true))
|
||||
continue; // CAM slot can't be used with this device
|
||||
bool ndr;
|
||||
if (device[i]->ProvidesChannel(Channel, Priority, &ndr)) { // this device is basically able to do the job
|
||||
if (NumUsableSlots && !HasInternalCam && device[i]->CamSlot() && device[i]->CamSlot() != CamSlots.Get(j))
|
||||
ndr = true; // using a different CAM slot requires detaching receivers
|
||||
bool ndr = false;
|
||||
bool TunedToTransponder = device[i]->IsTunedToTransponder(Channel);
|
||||
if (TunedToTransponder || device[i]->ProvidesChannel(Channel, Priority, &ndr)) { // this device is basically able to do the job
|
||||
bool OccupiedOtherTransponder = !TunedToTransponder && device[i]->Occupied();
|
||||
if (OccupiedOtherTransponder)
|
||||
ndr = true;
|
||||
if (NumUsableSlots && !HasInternalCam) {
|
||||
if (cCamSlot *csi = device[i]->CamSlot()) {
|
||||
cCamSlot *csj = CamSlots.Get(j);
|
||||
if ((csj->MtdActive() ? csi->MasterSlot() : csi) != csj)
|
||||
ndr = true; // using a different CAM slot requires detaching receivers
|
||||
}
|
||||
}
|
||||
// Put together an integer number that reflects the "impact" using
|
||||
// this device would have on the overall system. Each condition is represented
|
||||
// by one bit in the number (or several bits, if the condition is actually
|
||||
@ -289,17 +306,18 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
|
||||
// to their individual severity, where the one listed first will make the most
|
||||
// difference, because it results in the most significant bit of the result.
|
||||
uint32_t imp = 0;
|
||||
imp <<= 1; imp |= (LiveView && NumUsableSlots && !HasInternalCam) ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), CamSlots.Get(j)->MasterSlotNumber()) || ndr : 0; // prefer CAMs that are known to decrypt this channel for live viewing, if we don't need to detach existing receivers
|
||||
imp <<= 1; imp |= LiveView ? !device[i]->IsPrimaryDevice() || ndr : 0; // prefer the primary device for live viewing if we don't need to detach existing receivers
|
||||
imp <<= 1; imp |= !device[i]->Receiving() && (device[i] != cTransferControl::ReceiverDevice() || device[i]->IsPrimaryDevice()) || ndr; // use receiving devices if we don't need to detach existing receivers, but avoid primary device in local transfer mode
|
||||
imp <<= 1; imp |= device[i]->Receiving(); // avoid devices that are receiving
|
||||
imp <<= 4; imp |= GetClippedNumProvidedSystems(4, device[i]) - 1; // avoid cards which support multiple delivery systems
|
||||
imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device
|
||||
imp <<= 1; imp |= device[i]->Receiving() || OccupiedOtherTransponder; // avoid devices that are receiving
|
||||
imp <<= 5; imp |= GetClippedNumProvidedSystems(5, device[i]) - 1; // avoid cards which support multiple delivery systems
|
||||
imp <<= 8; imp |= device[i]->Priority() - IDLEPRIORITY; // use the device with the lowest priority (- IDLEPRIORITY to assure that values -100..99 can be used)
|
||||
imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device
|
||||
imp <<= 8; imp |= ((NumUsableSlots && !HasInternalCam) ? SlotPriority[j] : IDLEPRIORITY) - IDLEPRIORITY;// use the CAM slot with the lowest priority (- IDLEPRIORITY to assure that values -100..99 can be used)
|
||||
imp <<= 1; imp |= ndr; // avoid devices if we need to detach existing receivers
|
||||
imp <<= 1; imp |= (NumUsableSlots || InternalCamNeeded) ? 0 : device[i]->HasCi(); // avoid cards with Common Interface for FTA channels
|
||||
imp <<= 1; imp |= device[i]->AvoidRecording(); // avoid SD full featured cards
|
||||
imp <<= 1; imp |= (NumUsableSlots && !HasInternalCam) ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), j + 1) : 0; // prefer CAMs that are known to decrypt this channel
|
||||
imp <<= 1; imp |= (NumUsableSlots && !HasInternalCam) ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), CamSlots.Get(j)->MasterSlotNumber()) : 0; // prefer CAMs that are known to decrypt this channel
|
||||
imp <<= 1; imp |= device[i]->IsPrimaryDevice(); // avoid the primary device
|
||||
if (imp < Impact) {
|
||||
// This device has less impact than any previous one, so we take it.
|
||||
@ -309,21 +327,95 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
|
||||
if (NumUsableSlots && !HasInternalCam)
|
||||
s = CamSlots.Get(j);
|
||||
}
|
||||
//dsyslog("device %d provides channel %d prio %d ndr %d imp %.8X", device[i]->DeviceNumber() + 1, Channel->Number(), Priority, ndr, imp);
|
||||
}
|
||||
}
|
||||
if (!NumUsableSlots)
|
||||
break; // no CAM necessary, so just one loop over the devices
|
||||
}
|
||||
if (d && !Query) {
|
||||
if (NeedsDetachReceivers)
|
||||
if (d) {
|
||||
if (!Query && NeedsDetachReceivers)
|
||||
d->DetachAllReceivers();
|
||||
if (s) {
|
||||
if (s->Device() != d) {
|
||||
if (s->Device())
|
||||
s->Device()->DetachAllReceivers();
|
||||
if (d->CamSlot())
|
||||
d->CamSlot()->Assign(NULL);
|
||||
s->Assign(d);
|
||||
// Some of the following statements could probably be combined, but let's keep them
|
||||
// explicit so we can clearly see every single aspect of the decisions made here.
|
||||
if (d->CamSlot()) {
|
||||
if (s->MtdActive()) {
|
||||
if (s == d->CamSlot()->MasterSlot()) {
|
||||
// device d already has a proper CAM slot, so nothing to do here
|
||||
}
|
||||
else {
|
||||
// device d has a CAM slot, but it's not the right one
|
||||
if (!Query) {
|
||||
d->CamSlot()->Assign(NULL);
|
||||
s = s->MtdSpawn();
|
||||
s->Assign(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (s->Device()) {
|
||||
if (s->Device() != d) {
|
||||
// CAM slot s is currently assigned to a different device than d
|
||||
if (Priority > s->Priority()) {
|
||||
if (!Query) {
|
||||
d->CamSlot()->Assign(NULL);
|
||||
s->Assign(d);
|
||||
}
|
||||
}
|
||||
else {
|
||||
d = NULL;
|
||||
s = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// device d already has a proper CAM slot, so nothing to do here
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (s != d->CamSlot()) {
|
||||
// device d has a CAM slot, but it's not the right one
|
||||
if (!Query) {
|
||||
d->CamSlot()->Assign(NULL);
|
||||
s->Assign(d);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// device d already has a proper CAM slot, so nothing to do here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// device d has no CAM slot, ...
|
||||
if (s->MtdActive()) {
|
||||
// ... so we assign s with MTD support
|
||||
if (!Query) {
|
||||
s = s->MtdSpawn();
|
||||
s->Assign(d);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// CAM slot s has no MTD support ...
|
||||
if (s->Device()) {
|
||||
// ... but it is assigned to a different device, so we reassign it to d
|
||||
if (Priority > s->Priority()) {
|
||||
if (!Query) {
|
||||
s->Device()->DetachAllReceivers();
|
||||
s->Assign(d);
|
||||
}
|
||||
}
|
||||
else {
|
||||
d = NULL;
|
||||
s = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ... and is not assigned to any device, so we just assign it to d
|
||||
if (!Query)
|
||||
s->Assign(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (d->CamSlot() && !d->CamSlot()->IsDecrypting())
|
||||
@ -341,8 +433,9 @@ cDevice *cDevice::GetDeviceForTransponder(const cChannel *Channel, int Priority)
|
||||
return d; // if any device is tuned to the transponder, we're done
|
||||
if (d->ProvidesTransponder(Channel)) {
|
||||
if (d->MaySwitchTransponder(Channel))
|
||||
Device = d; // this device may switch to the transponder without disturbing any receiver or live view
|
||||
else if (!d->Occupied() && d->MaySwitchTransponder(Channel)) { // MaySwitchTransponder() implicitly calls Occupied()
|
||||
return d; // this device may switch to the transponder without disturbing any receiver or live view
|
||||
else if (!d->Occupied(Priority) && !d->IsBonded() && d->Priority(true) < LIVEPRIORITY) { // MaySwitchTransponder() implicitly calls Occupied()
|
||||
// we select only devices with priority < LIVEPRIORITY, so device can be switched without impact on recordings or live viewing
|
||||
if (d->Priority() < Priority && (!Device || d->Priority() < Device->Priority()))
|
||||
Device = d; // use this one only if no other with less impact can be found
|
||||
}
|
||||
@ -352,6 +445,12 @@ cDevice *cDevice::GetDeviceForTransponder(const cChannel *Channel, int Priority)
|
||||
return Device;
|
||||
}
|
||||
|
||||
void cDevice::ReleaseCamSlot(void)
|
||||
{
|
||||
if (camSlot && !camSlot->IsDecrypting() && !camSlot->IsActivating())
|
||||
camSlot->Assign(NULL);
|
||||
}
|
||||
|
||||
bool cDevice::HasCi(void)
|
||||
{
|
||||
return false;
|
||||
@ -445,11 +544,12 @@ void cDevice::GetOsdSize(int &Width, int &Height, double &PixelAspect)
|
||||
PixelAspect = 1.0;
|
||||
}
|
||||
|
||||
//#define PRINTPIDS(s) { char b[500]; char *q = b; q += sprintf(q, "%d %s ", CardIndex(), s); for (int i = 0; i < MAXPIDHANDLES; i++) q += sprintf(q, " %s%4d %d", i == ptOther ? "* " : "", pidHandles[i].pid, pidHandles[i].used); dsyslog("%s", b); }
|
||||
//#define PRINTPIDS(s) { char b[500]; char *q = b; q += sprintf(q, "%d %s ", DeviceNumber() + 1, s); for (int i = 0; i < MAXPIDHANDLES; i++) q += sprintf(q, " %s%4d %d", i == ptOther ? "* " : "", pidHandles[i].pid, pidHandles[i].used); dsyslog("%s", b); }
|
||||
#define PRINTPIDS(s)
|
||||
|
||||
bool cDevice::HasPid(int Pid) const
|
||||
{
|
||||
cMutexLock MutexLock(&mutexPids);
|
||||
for (int i = 0; i < MAXPIDHANDLES; i++) {
|
||||
if (pidHandles[i].pid == Pid)
|
||||
return true;
|
||||
@ -459,6 +559,7 @@ bool cDevice::HasPid(int Pid) const
|
||||
|
||||
bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexPids);
|
||||
if (Pid || PidType == ptPcr) {
|
||||
int n = -1;
|
||||
int a = -1;
|
||||
@ -478,7 +579,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
|
||||
// It's a special PID that may have to be switched into "tap" mode
|
||||
PRINTPIDS("A");
|
||||
if (!SetPid(&pidHandles[n], n, true)) {
|
||||
esyslog("ERROR: can't set PID %d on device %d", Pid, CardIndex() + 1);
|
||||
esyslog("ERROR: can't set PID %d on device %d", Pid, DeviceNumber() + 1);
|
||||
if (PidType <= ptTeletext)
|
||||
DetachAll(Pid);
|
||||
DelPid(Pid, PidType);
|
||||
@ -499,7 +600,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
|
||||
n = a;
|
||||
}
|
||||
else {
|
||||
esyslog("ERROR: no free slot for PID %d on device %d", Pid, CardIndex() + 1);
|
||||
esyslog("ERROR: no free slot for PID %d on device %d", Pid, DeviceNumber() + 1);
|
||||
return false;
|
||||
}
|
||||
if (n >= 0) {
|
||||
@ -508,7 +609,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
|
||||
pidHandles[n].used = 1;
|
||||
PRINTPIDS("C");
|
||||
if (!SetPid(&pidHandles[n], n, true)) {
|
||||
esyslog("ERROR: can't set PID %d on device %d", Pid, CardIndex() + 1);
|
||||
esyslog("ERROR: can't set PID %d on device %d", Pid, DeviceNumber() + 1);
|
||||
if (PidType <= ptTeletext)
|
||||
DetachAll(Pid);
|
||||
DelPid(Pid, PidType);
|
||||
@ -523,6 +624,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
|
||||
|
||||
void cDevice::DelPid(int Pid, ePidType PidType)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexPids);
|
||||
if (Pid || PidType == ptPcr) {
|
||||
int n = -1;
|
||||
if (PidType == ptPcr)
|
||||
@ -558,6 +660,7 @@ bool cDevice::SetPid(cPidHandle *Handle, int Type, bool On)
|
||||
|
||||
void cDevice::DelLivePids(void)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexPids);
|
||||
for (int i = ptAudio; i < ptOther; i++) {
|
||||
if (pidHandles[i].pid)
|
||||
DelPid(pidHandles[i].pid, ePidType(i));
|
||||
@ -578,11 +681,11 @@ void cDevice::StartSectionHandler(void)
|
||||
void cDevice::StopSectionHandler(void)
|
||||
{
|
||||
if (sectionHandler) {
|
||||
delete sectionHandler; // automatically detaches filters
|
||||
delete nitFilter;
|
||||
delete sdtFilter;
|
||||
delete patFilter;
|
||||
delete eitFilter;
|
||||
delete sectionHandler;
|
||||
nitFilter = NULL;
|
||||
sdtFilter = NULL;
|
||||
patFilter = NULL;
|
||||
@ -634,6 +737,17 @@ bool cDevice::DeviceHooksProvidesTransponder(const cChannel *Channel) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cDevice::DeviceHooksProvidesEIT(void) const
|
||||
{
|
||||
cDeviceHook *Hook = deviceHooks.First();
|
||||
while (Hook) {
|
||||
if (!Hook->DeviceProvidesEIT(this))
|
||||
return false;
|
||||
Hook = deviceHooks.Next(Hook);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cDevice::ProvidesTransponder(const cChannel *Channel) const
|
||||
{
|
||||
return false;
|
||||
@ -668,6 +782,11 @@ const cPositioner *cDevice::Positioner(void) const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool cDevice::SignalStats(int &Valid, double *Strength, double *Cnr, double *BerPre, double *BerPost, double *Per, int *Status) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int cDevice::SignalStrength(void) const
|
||||
{
|
||||
return -1;
|
||||
@ -690,21 +809,32 @@ bool cDevice::IsTunedToTransponder(const cChannel *Channel) const
|
||||
|
||||
bool cDevice::MaySwitchTransponder(const cChannel *Channel) const
|
||||
{
|
||||
return time(NULL) > occupiedTimeout && !Receiving() && !(pidHandles[ptAudio].pid || pidHandles[ptVideo].pid || pidHandles[ptDolby].pid);
|
||||
return !Occupied() && !Receiving() && !(pidHandles[ptAudio].pid || pidHandles[ptVideo].pid || pidHandles[ptDolby].pid);
|
||||
}
|
||||
|
||||
void cDevice::SetPowerSaveMode(bool On)
|
||||
{
|
||||
}
|
||||
|
||||
void cDevice::SetPowerSaveIfUnused(void)
|
||||
{
|
||||
if (!Occupied() && !Receiving() && !(pidHandles[ptAudio].pid || pidHandles[ptVideo].pid || pidHandles[ptDolby].pid))
|
||||
SetPowerSaveMode(true);
|
||||
}
|
||||
|
||||
bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView)
|
||||
{
|
||||
if (LiveView) {
|
||||
isyslog("switching to channel %d (%s)", Channel->Number(), Channel->Name());
|
||||
isyslog("switching to channel %d %s (%s)", Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name());
|
||||
cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer
|
||||
// and, if decrypted, this removes the now superfluous PIDs from the CAM, too
|
||||
}
|
||||
for (int i = 3; i--;) {
|
||||
switch (SetChannel(Channel, LiveView)) {
|
||||
case scrOk: return true;
|
||||
case scrNotAvailable: Skins.Message(mtInfo, tr("Channel not available!"));
|
||||
case scrNotAvailable: Skins.QueueMessage(mtInfo, tr("Channel not available!"));
|
||||
return false;
|
||||
case scrNoTransfer: Skins.Message(mtError, tr("Can't start Transfer Mode!"));
|
||||
case scrNoTransfer: Skins.QueueMessage(mtError, tr("Can't start Transfer Mode!"));
|
||||
return false;
|
||||
case scrFailed: break; // loop will retry
|
||||
default: esyslog("ERROR: invalid return value from SetChannel");
|
||||
@ -720,6 +850,7 @@ bool cDevice::SwitchChannel(int Direction)
|
||||
Direction = sgn(Direction);
|
||||
if (Direction) {
|
||||
cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer
|
||||
// and, if decrypted, this removes the now superfluous PIDs from the CAM, too
|
||||
int n = CurrentChannel() + Direction;
|
||||
int first = n;
|
||||
LOCK_CHANNELS_READ;
|
||||
@ -740,22 +871,30 @@ bool cDevice::SwitchChannel(int Direction)
|
||||
result = true;
|
||||
}
|
||||
else if (n != first)
|
||||
Skins.Message(mtError, tr("Channel not available!"));
|
||||
Skins.QueueMessage(mtError, tr("Channel not available!"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexChannel); // to avoid a race between SVDRP CHAN and HasProgramme()
|
||||
cStatus::MsgChannelSwitch(this, 0, LiveView);
|
||||
|
||||
if (LiveView) {
|
||||
if (IsPrimaryDevice() && !Replaying() && !Transferring()) { // this is only for FF DVB cards!
|
||||
LOCK_CHANNELS_READ;
|
||||
if (const cChannel *ch = Channels->GetByNumber(currentChannel)) {
|
||||
if (patFilter)
|
||||
patFilter->Release(ch->Sid());
|
||||
}
|
||||
}
|
||||
StopReplay();
|
||||
DELETENULL(liveSubtitle);
|
||||
DELETENULL(dvbSubtitleConverter);
|
||||
}
|
||||
|
||||
cDevice *Device = (LiveView && IsPrimaryDevice()) ? GetDevice(Channel, LIVEPRIORITY, true) : this;
|
||||
cDevice *Device = (LiveView && IsPrimaryDevice(false)) ? GetDevice(Channel, LIVEPRIORITY, true) : this;
|
||||
|
||||
bool NeedsTransferMode = LiveView && Device != PrimaryDevice();
|
||||
// If the CAM slot wants the TS data, we need to switch to Transfer Mode:
|
||||
@ -787,11 +926,10 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
||||
// channel to it, for possible later decryption:
|
||||
if (camSlot)
|
||||
camSlot->AddChannel(Channel);
|
||||
SetPowerSaveMode(false);
|
||||
if (SetChannelDevice(Channel, LiveView)) {
|
||||
// Start section handling:
|
||||
if (sectionHandler) {
|
||||
if (patFilter)
|
||||
patFilter->Trigger(Channel->Sid());
|
||||
sectionHandler->SetChannel(Channel);
|
||||
sectionHandler->SetStatus(true);
|
||||
}
|
||||
@ -804,21 +942,26 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
||||
}
|
||||
|
||||
if (Result == scrOk) {
|
||||
if (LiveView && IsPrimaryDevice()) {
|
||||
currentChannel = Channel->Number();
|
||||
// Set the available audio tracks:
|
||||
ClrAvailableTracks();
|
||||
for (int i = 0; i < MAXAPIDS; i++)
|
||||
SetAvailableTrack(ttAudio, i, Channel->Apid(i), Channel->Alang(i));
|
||||
if (Setup.UseDolbyDigital) {
|
||||
for (int i = 0; i < MAXDPIDS; i++)
|
||||
SetAvailableTrack(ttDolby, i, Channel->Dpid(i), Channel->Dlang(i));
|
||||
if (LiveView) {
|
||||
if (IsPrimaryDevice(false))
|
||||
currentChannel = Channel->Number();
|
||||
if (IsPrimaryDevice()) {
|
||||
if (patFilter) // this is only for FF DVB cards!
|
||||
patFilter->Request(Channel->Sid());
|
||||
// Set the available audio tracks:
|
||||
ClrAvailableTracks();
|
||||
for (int i = 0; i < MAXAPIDS; i++)
|
||||
SetAvailableTrack(ttAudio, i, Channel->Apid(i), Channel->Alang(i));
|
||||
if (Setup.UseDolbyDigital) {
|
||||
for (int i = 0; i < MAXDPIDS; i++)
|
||||
SetAvailableTrack(ttDolby, i, Channel->Dpid(i), Channel->Dlang(i));
|
||||
}
|
||||
for (int i = 0; i < MAXSPIDS; i++)
|
||||
SetAvailableTrack(ttSubtitle, i, Channel->Spid(i), Channel->Slang(i));
|
||||
if (!NeedsTransferMode)
|
||||
EnsureAudioTrack(true);
|
||||
EnsureSubtitleTrack();
|
||||
}
|
||||
for (int i = 0; i < MAXSPIDS; i++)
|
||||
SetAvailableTrack(ttSubtitle, i, Channel->Spid(i), Channel->Slang(i));
|
||||
if (!NeedsTransferMode)
|
||||
EnsureAudioTrack(true);
|
||||
EnsureSubtitleTrack();
|
||||
}
|
||||
cStatus::MsgChannelSwitch(this, Channel->Number(), LiveView); // only report status if channel switch successful
|
||||
}
|
||||
@ -830,21 +973,34 @@ void cDevice::ForceTransferMode(void)
|
||||
{
|
||||
if (!cTransferControl::ReceiverDevice()) {
|
||||
LOCK_CHANNELS_READ;
|
||||
if (const cChannel *Channel = Channels->GetByNumber(CurrentChannel()))
|
||||
if (const cChannel *Channel = Channels->GetByNumber(CurrentChannel())) {
|
||||
SetPowerSaveMode(false);
|
||||
SetChannelDevice(Channel, false); // this implicitly starts Transfer Mode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cDevice::Occupied(void) const
|
||||
int cDevice::Occupied(int Priority) const
|
||||
{
|
||||
if (Priority > occupiedPriority)
|
||||
return 0;
|
||||
int Seconds = occupiedTimeout - time(NULL);
|
||||
return Seconds > 0 ? Seconds : 0;
|
||||
}
|
||||
|
||||
void cDevice::SetOccupied(int Seconds)
|
||||
void cDevice::SetOccupied(int Seconds, int Priority, time_t From)
|
||||
{
|
||||
if (Seconds >= 0)
|
||||
occupiedTimeout = time(NULL) + min(Seconds, MAXOCCUPIEDTIMEOUT);
|
||||
if (Seconds < 0)
|
||||
return;
|
||||
if (From == 0)
|
||||
From = time(NULL);
|
||||
if (From == occupiedFrom)
|
||||
occupiedPriority = max(Priority, occupiedPriority);
|
||||
else {
|
||||
occupiedPriority = Priority;
|
||||
occupiedFrom = From;
|
||||
}
|
||||
occupiedTimeout = From + min(Seconds, MAXOCCUPIEDTIMEOUT);
|
||||
}
|
||||
|
||||
bool cDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
||||
@ -859,6 +1015,7 @@ bool cDevice::HasLock(int TimeoutMs) const
|
||||
|
||||
bool cDevice::HasProgramme(void) const
|
||||
{
|
||||
cMutexLock MutexLock(&mutexChannel); // to avoid a race between SVDRP CHAN and HasProgramme()
|
||||
return Replaying() || pidHandles[ptAudio].pid || pidHandles[ptVideo].pid;
|
||||
}
|
||||
|
||||
@ -1472,7 +1629,6 @@ int cDevice::PlayTsSubtitle(const uchar *Data, int Length)
|
||||
return Length;
|
||||
}
|
||||
|
||||
//TODO detect and report continuity errors?
|
||||
int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
|
||||
{
|
||||
int Played = 0;
|
||||
@ -1487,13 +1643,8 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
|
||||
}
|
||||
else {
|
||||
while (Length >= TS_SIZE) {
|
||||
if (Data[0] != TS_SYNC_BYTE) {
|
||||
int Skipped = 1;
|
||||
while (Skipped < Length && (Data[Skipped] != TS_SYNC_BYTE || Length - Skipped > TS_SIZE && Data[Skipped + TS_SIZE] != TS_SYNC_BYTE))
|
||||
Skipped++;
|
||||
esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
|
||||
if (int Skipped = TS_SYNC(Data, Length))
|
||||
return Played + Skipped;
|
||||
}
|
||||
int Pid = TsPid(Data);
|
||||
if (TsHasPayload(Data)) { // silently ignore TS packets w/o payload
|
||||
int PayloadOffset = TsPayloadOffset(Data);
|
||||
@ -1541,11 +1692,13 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
|
||||
return Played;
|
||||
}
|
||||
|
||||
int cDevice::Priority(void) const
|
||||
int cDevice::Priority(bool IgnoreOccupied) const
|
||||
{
|
||||
int priority = IDLEPRIORITY;
|
||||
if (IsPrimaryDevice() && !Replaying() && HasProgramme())
|
||||
priority = TRANSFERPRIORITY; // we use the same value here, no matter whether it's actual Transfer Mode or real live viewing
|
||||
if (!IgnoreOccupied && time(NULL) <= occupiedTimeout && occupiedPriority > priority)
|
||||
priority = occupiedPriority - 1; // so timers with occupiedPriority can start
|
||||
cMutexLock MutexLock(&mutexReceiver);
|
||||
for (int i = 0; i < MAXRECEIVERS; i++) {
|
||||
if (receiver[i])
|
||||
@ -1570,7 +1723,8 @@ bool cDevice::Receiving(bool Dummy) const
|
||||
}
|
||||
|
||||
#define TS_SCRAMBLING_TIMEOUT 3 // seconds to wait until a TS becomes unscrambled
|
||||
#define TS_SCRAMBLING_TIME_OK 10 // seconds before a Channel/CAM combination is marked as known to decrypt
|
||||
#define TS_SCRAMBLING_TIME_OK 3 // seconds before a Channel/CAM combination is marked as known to decrypt
|
||||
#define EIT_INJECTION_TIME 10 // seconds for which to inject EIT event
|
||||
|
||||
void cDevice::Action(void)
|
||||
{
|
||||
@ -1580,40 +1734,58 @@ void cDevice::Action(void)
|
||||
uchar *b = NULL;
|
||||
if (GetTSPacket(b)) {
|
||||
if (b) {
|
||||
int Pid = TsPid(b);
|
||||
// Check whether the TS packets are scrambled:
|
||||
bool DetachReceivers = false;
|
||||
bool DescramblingOk = false;
|
||||
int CamSlotNumber = 0;
|
||||
cCamSlot *cs = NULL;
|
||||
if (startScrambleDetection) {
|
||||
cs = CamSlot();
|
||||
CamSlotNumber = cs ? cs->SlotNumber() : 0;
|
||||
if (CamSlotNumber) {
|
||||
int t = time(NULL) - startScrambleDetection;
|
||||
if (TsIsScrambled(b)) {
|
||||
if (t > TS_SCRAMBLING_TIMEOUT)
|
||||
DetachReceivers = true;
|
||||
}
|
||||
else if (t > TS_SCRAMBLING_TIME_OK) {
|
||||
DescramblingOk = true;
|
||||
startScrambleDetection = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Distribute the packet to all attached receivers:
|
||||
Lock();
|
||||
cCamSlot *cs = CamSlot();
|
||||
if (cs)
|
||||
cs->TsPostProcess(b);
|
||||
int Pid = TsPid(b);
|
||||
bool IsScrambled = TsIsScrambled(b);
|
||||
for (int i = 0; i < MAXRECEIVERS; i++) {
|
||||
if (receiver[i] && receiver[i]->WantsPid(Pid)) {
|
||||
if (DetachReceivers && cs && (!cs->IsActivating() || receiver[i]->Priority() >= LIVEPRIORITY)) {
|
||||
dsyslog("detaching receiver - won't decrypt channel %s with CAM %d", *receiver[i]->ChannelID().ToString(), CamSlotNumber);
|
||||
ChannelCamRelations.SetChecked(receiver[i]->ChannelID(), CamSlotNumber);
|
||||
Detach(receiver[i]);
|
||||
cMutexLock MutexLock(&mutexReceiver);
|
||||
cReceiver *Receiver = receiver[i];
|
||||
if (Receiver && Receiver->WantsPid(Pid)) {
|
||||
Receiver->Receive(b, TS_SIZE);
|
||||
// Check whether the TS packet is scrambled:
|
||||
if (Receiver->startScrambleDetection) {
|
||||
if (cs) {
|
||||
int CamSlotNumber = cs->MasterSlotNumber();
|
||||
if (Receiver->lastScrambledPacket < Receiver->startScrambleDetection)
|
||||
Receiver->lastScrambledPacket = Receiver->startScrambleDetection;
|
||||
time_t Now = time(NULL);
|
||||
if (IsScrambled) {
|
||||
Receiver->lastScrambledPacket = Now;
|
||||
if (Now - Receiver->startScrambleDetection > Receiver->scramblingTimeout) {
|
||||
if (!cs->IsActivating() || Receiver->Priority() >= LIVEPRIORITY) {
|
||||
if (Receiver->ChannelID().Valid()) {
|
||||
dsyslog("CAM %d: won't decrypt channel %s, detaching receiver", CamSlotNumber, *Receiver->ChannelID().ToString());
|
||||
ChannelCamRelations.SetChecked(Receiver->ChannelID(), CamSlotNumber);
|
||||
}
|
||||
Detach(Receiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Now - Receiver->lastScrambledPacket > TS_SCRAMBLING_TIME_OK) {
|
||||
if (Receiver->ChannelID().Valid()) {
|
||||
dsyslog("CAM %d: decrypts channel %s", CamSlotNumber, *Receiver->ChannelID().ToString());
|
||||
ChannelCamRelations.SetDecrypt(Receiver->ChannelID(), CamSlotNumber);
|
||||
}
|
||||
Receiver->startScrambleDetection = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Inject EIT event to avoid the CAMs parental rating prompt:
|
||||
if (Receiver->startEitInjection) {
|
||||
time_t Now = time(NULL);
|
||||
if (cCamSlot *cs = CamSlot()) {
|
||||
if (Now != Receiver->lastEitInjection) { // once per second
|
||||
cs->InjectEit(Receiver->ChannelID().Sid());
|
||||
Receiver->lastEitInjection = Now;
|
||||
}
|
||||
}
|
||||
if (Now - Receiver->startEitInjection > EIT_INJECTION_TIME)
|
||||
Receiver->startEitInjection = 0;
|
||||
}
|
||||
else
|
||||
receiver[i]->Receive(b, TS_SIZE);
|
||||
if (DescramblingOk)
|
||||
ChannelCamRelations.SetDecrypt(receiver[i]->ChannelID(), CamSlotNumber);
|
||||
}
|
||||
}
|
||||
Unlock();
|
||||
@ -1651,7 +1823,7 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
|
||||
#ifdef WAIT_FOR_TUNER_LOCK
|
||||
#define TUNER_LOCK_TIMEOUT 5000 // ms
|
||||
if (!HasLock(TUNER_LOCK_TIMEOUT)) {
|
||||
esyslog("ERROR: device %d has no lock, can't attach receiver!", CardIndex() + 1);
|
||||
esyslog("ERROR: device %d has no lock, can't attach receiver!", DeviceNumber() + 1);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@ -1666,14 +1838,26 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
|
||||
}
|
||||
}
|
||||
Receiver->Activate(true);
|
||||
Lock();
|
||||
Receiver->device = this;
|
||||
receiver[i] = Receiver;
|
||||
Unlock();
|
||||
if (camSlot && Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver
|
||||
camSlot->StartDecrypting();
|
||||
startScrambleDetection = time(NULL);
|
||||
if (camSlot->WantsTsData()) {
|
||||
Receiver->lastEitInjection = 0;
|
||||
Receiver->startEitInjection = time(NULL);
|
||||
}
|
||||
if (CamSlots.NumReadyMasterSlots() > 1) { // don't try different CAMs if there is only one
|
||||
Receiver->startScrambleDetection = time(NULL);
|
||||
Receiver->scramblingTimeout = TS_SCRAMBLING_TIMEOUT;
|
||||
bool KnownToDecrypt = ChannelCamRelations.CamDecrypt(Receiver->ChannelID(), camSlot->MasterSlotNumber());
|
||||
if (KnownToDecrypt)
|
||||
Receiver->scramblingTimeout *= 9; // give it time to receive ECM/EMM (must be less than MAXBROKENTIMEOUT in recorder.c!)
|
||||
if (Receiver->ChannelID().Valid())
|
||||
dsyslog("CAM %d: %sknown to decrypt channel %s (scramblingTimeout = %ds)", camSlot->MasterSlotNumber(), KnownToDecrypt ? "" : "not ", *Receiver->ChannelID().ToString(), Receiver->scramblingTimeout);
|
||||
}
|
||||
}
|
||||
if (patFilter && Receiver->ChannelID().Valid())
|
||||
patFilter->Request(Receiver->ChannelID().Sid());
|
||||
Start();
|
||||
return true;
|
||||
}
|
||||
@ -1682,30 +1866,30 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
|
||||
return false;
|
||||
}
|
||||
|
||||
void cDevice::Detach(cReceiver *Receiver)
|
||||
void cDevice::Detach(cReceiver *Receiver, bool ReleaseCam)
|
||||
{
|
||||
if (!Receiver || Receiver->device != this)
|
||||
return;
|
||||
bool receiversLeft = false;
|
||||
cMutexLock MutexLock(&mutexReceiver);
|
||||
mutexReceiver.Lock();
|
||||
for (int i = 0; i < MAXRECEIVERS; i++) {
|
||||
if (receiver[i] == Receiver) {
|
||||
Lock();
|
||||
if (receiver[i] == Receiver)
|
||||
receiver[i] = NULL;
|
||||
Receiver->device = NULL;
|
||||
Unlock();
|
||||
Receiver->Activate(false);
|
||||
for (int n = 0; n < Receiver->numPids; n++)
|
||||
DelPid(Receiver->pids[n]);
|
||||
}
|
||||
else if (receiver[i])
|
||||
receiversLeft = true;
|
||||
}
|
||||
if (patFilter && Receiver->ChannelID().Valid())
|
||||
patFilter->Release(Receiver->ChannelID().Sid());
|
||||
mutexReceiver.Unlock();
|
||||
Receiver->device = NULL;
|
||||
Receiver->Activate(false);
|
||||
for (int n = 0; n < Receiver->numPids; n++)
|
||||
DelPid(Receiver->pids[n]);
|
||||
if (camSlot) {
|
||||
if (Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver
|
||||
camSlot->StartDecrypting();
|
||||
if (!camSlot->IsDecrypting() && !camSlot->IsActivating())
|
||||
camSlot->Assign(NULL);
|
||||
if (ReleaseCam)
|
||||
ReleaseCamSlot();
|
||||
}
|
||||
}
|
||||
if (!receiversLeft)
|
||||
@ -1719,8 +1903,9 @@ void cDevice::DetachAll(int Pid)
|
||||
for (int i = 0; i < MAXRECEIVERS; i++) {
|
||||
cReceiver *Receiver = receiver[i];
|
||||
if (Receiver && Receiver->WantsPid(Pid))
|
||||
Detach(Receiver);
|
||||
Detach(Receiver, false);
|
||||
}
|
||||
ReleaseCamSlot();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1728,17 +1913,18 @@ void cDevice::DetachAllReceivers(void)
|
||||
{
|
||||
cMutexLock MutexLock(&mutexReceiver);
|
||||
for (int i = 0; i < MAXRECEIVERS; i++)
|
||||
Detach(receiver[i]);
|
||||
Detach(receiver[i], false);
|
||||
ReleaseCamSlot();
|
||||
}
|
||||
|
||||
// --- cTSBuffer -------------------------------------------------------------
|
||||
|
||||
cTSBuffer::cTSBuffer(int File, int Size, int CardIndex)
|
||||
cTSBuffer::cTSBuffer(int File, int Size, int DeviceNumber)
|
||||
{
|
||||
SetDescription("device %d TS buffer", CardIndex);
|
||||
SetDescription("device %d TS buffer", DeviceNumber);
|
||||
f = File;
|
||||
cardIndex = CardIndex;
|
||||
delivered = false;
|
||||
deviceNumber = DeviceNumber;
|
||||
delivered = 0;
|
||||
ringBuffer = new cRingBufferLinear(Size, TS_SIZE, true, "TS");
|
||||
ringBuffer->SetTimeouts(100, 100);
|
||||
ringBuffer->SetIoThrottle();
|
||||
@ -1762,24 +1948,27 @@ void cTSBuffer::Action(void)
|
||||
int r = ringBuffer->Read(f);
|
||||
if (r < 0 && FATALERRNO) {
|
||||
if (errno == EOVERFLOW)
|
||||
esyslog("ERROR: driver buffer overflow on device %d", cardIndex);
|
||||
esyslog("ERROR: driver buffer overflow on device %d", deviceNumber);
|
||||
else {
|
||||
LOG_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cCondWait::SleepMs(10); // avoids small chunks of data, which cause high CPU usage, esp. on ARM CPUs
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uchar *cTSBuffer::Get(int *Available)
|
||||
uchar *cTSBuffer::Get(int *Available, bool CheckAvailable)
|
||||
{
|
||||
int Count = 0;
|
||||
if (delivered) {
|
||||
ringBuffer->Del(TS_SIZE);
|
||||
delivered = false;
|
||||
ringBuffer->Del(delivered);
|
||||
delivered = 0;
|
||||
}
|
||||
if (CheckAvailable && ringBuffer->Available() < TS_SIZE)
|
||||
return NULL;
|
||||
uchar *p = ringBuffer->Get(Count);
|
||||
if (p && Count >= TS_SIZE) {
|
||||
if (*p != TS_SYNC_BYTE) {
|
||||
@ -1790,10 +1979,10 @@ uchar *cTSBuffer::Get(int *Available)
|
||||
}
|
||||
}
|
||||
ringBuffer->Del(Count);
|
||||
esyslog("ERROR: skipped %d bytes to sync on TS packet on device %d", Count, cardIndex);
|
||||
esyslog("ERROR: skipped %d bytes to sync on TS packet on device %d", Count, deviceNumber);
|
||||
return NULL;
|
||||
}
|
||||
delivered = true;
|
||||
delivered = TS_SIZE;
|
||||
if (Available)
|
||||
*Available = Count;
|
||||
return p;
|
||||
@ -1803,6 +1992,5 @@ uchar *cTSBuffer::Get(int *Available)
|
||||
|
||||
void cTSBuffer::Skip(int Count)
|
||||
{
|
||||
ringBuffer->Del(Count);
|
||||
delivered = false;
|
||||
delivered = Count;
|
||||
}
|
||||
|
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