1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
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.
|