mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Converted to the new API plus several small enhancements
This commit is contained in:
parent
1ef2b1d3a1
commit
c40e4eb96e
@ -42,6 +42,7 @@ Bastian Guse <bastian@nocopy.de>
|
||||
Matthias Schniedermeyer <ms@citd.de>
|
||||
for implementing the 'MarkInstantRecord' setup option
|
||||
for his "schnitt" tools
|
||||
for his "master-timer" tool
|
||||
|
||||
Miha Setina <mihasetina@softhome.net>
|
||||
for translating the OSD texts to the Slovenian language
|
||||
@ -54,6 +55,7 @@ Deti Fliegl <deti@fliegl.de>
|
||||
|
||||
Dave Chapman <dave@dchapman.com>
|
||||
for implementing support for the teletext PID
|
||||
for his great support in switching to the NAPI
|
||||
|
||||
Hans-Peter Raschke <Hans-Peter.Raschke@Wintermann-DatenService.de>
|
||||
for his support in adapting VDR to DVB-C
|
||||
@ -70,3 +72,6 @@ Arnold Niessen <niessen@iae.nl> <arnold.niessen@philips.com>
|
||||
|
||||
Jürgen Sauer <jojo@automatix.de>
|
||||
for implementing the -t option to set the controlling terminal
|
||||
|
||||
Benjamin Reichardt <reichard@math.uni-goettingen.de>
|
||||
for his help in debugging the transition to the new API
|
||||
|
8
FORMATS
8
FORMATS
@ -13,7 +13,7 @@ Video Disk Recorder File Formats
|
||||
|
||||
A "channel definition" is a line with channel data, where the fields
|
||||
are separated by ':' characters:
|
||||
Example: "RTL:12188:h:1:27500:163:104:0:0:12003"
|
||||
Example: "RTL:12188:h:1:27500:163:104:105:0:12003"
|
||||
|
||||
The fields in a channel definition have the following meaning (from left
|
||||
to right):
|
||||
@ -60,8 +60,10 @@ Video Disk Recorder File Formats
|
||||
(1..31)
|
||||
- Start time (first two digits for the hour, second two digits for the minutes)
|
||||
- End time (first two digits for the hour, second two digits for the minutes)
|
||||
- Priority (from 00 to 99, 00 = lowest prioity, 99 = highest priority)
|
||||
- Guaranteed lifetime of recording (in days)
|
||||
- Priority (from 0 to 99, 0 = lowest prioity, 99 = highest priority)
|
||||
- Guaranteed lifetime of recording (in days); 0 means that this recording may
|
||||
be automatically deleted by a new recording with higher priority, 99 means
|
||||
that this recording will never be automatically deleted
|
||||
- Name of timer (will be used to name the recording); if the name contains
|
||||
any ':' characters, these have to be replaced with '|'
|
||||
- Summary (any newline characters in the summary have to be replaced with '|';
|
||||
|
44
HISTORY
44
HISTORY
@ -290,7 +290,7 @@ Video Disk Recorder Revision History
|
||||
channel, if the timer currently occupying this DVB card doesn't need the
|
||||
CAM module (and thus can continue recording on a different DVB card).
|
||||
- The "Yellow" button in the "What's on now/next?" menus now displays the
|
||||
schedule of the current channel from that menu.
|
||||
schedule of the current channel from that menu.
|
||||
- All DVB cards in a multi-card system now write their EIT information into the
|
||||
same data structure.
|
||||
- If there is more than one DVB card in the system, the non-primary cards are
|
||||
@ -332,8 +332,8 @@ Video Disk Recorder Revision History
|
||||
- Implemented "On Disk Editing".
|
||||
- There is no more default 'timers.conf' file.
|
||||
- Added Italian language texts (thanks to Alberto Carraro).
|
||||
- Fixed starting a replay session when the program is currently in "transfer
|
||||
mode".
|
||||
- Fixed starting a replay session when the program is currently in 'Transfer
|
||||
Mode'.
|
||||
- Fixed setting/modifying timers via SVDRP with empty summary fields.
|
||||
- Fixed a problem with recordings that have a single quote character in their
|
||||
name (this is now mapped to 0x01).
|
||||
@ -452,3 +452,41 @@ Video Disk Recorder Revision History
|
||||
- Empty lines in config files no longer cause error messages.
|
||||
- New SVDRP command LSTE to list the EPG data.
|
||||
- The SVDRP HELP command now prints the topics in several columns.
|
||||
|
||||
2001-06-02: Version 0.80
|
||||
|
||||
- VDR now requires driver version 0.9.0 or higher.
|
||||
- Switched to the "new API" (thanks to Dave Chapman for his great support in
|
||||
this task).
|
||||
- New setup parameter "LnbSLOF" that defines the switching frequency of the LNB.
|
||||
- Fixed a bug in the EPG scanner with more than one DVB card.
|
||||
- Fixed checking for free disk space, so that it works with NFS mounted drives.
|
||||
- Files are now created with mode 644.
|
||||
- Fixed checking the exit status in the 'runvdr' script.
|
||||
- Activated loading the driver in 'runvdr'. Please read the comments in 'runvdr'
|
||||
for details.
|
||||
- The new "emergency exit" feature automatically triggers a restart of VDR (if
|
||||
used with 'runvdr', otherwise it simply exists) if
|
||||
* tuning the channel for a recording fails
|
||||
* no useful data is received within the first 1MB of a recording
|
||||
* no data is received within a recording for more than 5 seconds
|
||||
This should make sure that a recording is successfully restarted after any
|
||||
problems.
|
||||
- Processing the EIT data is now disabled during replay and 'Transfer Mode' in
|
||||
order to avoid video and audio glitches (there appears to be a bandwidth
|
||||
problem somewhere in the driver/firmware/hardware).
|
||||
- Due to the reduced amount of OSD memory provided by the driver the number of
|
||||
lines in the OSD had to be reduced by 2. By rearranging some of the display
|
||||
items the amount of visible information remained the same as before, though.
|
||||
If your DVB card has even less memory (which would result in only the
|
||||
channel switching display and the replay progress display being visible, but
|
||||
no Main menu), try reducing the constant 'MenuLines' in dvbapi.h (currently
|
||||
'13') even further.
|
||||
- There are two new setup parameters to define the "Default Priority" and
|
||||
"Default Lifetime" when creating a new timer event.
|
||||
- The meaning of the "Lifetime" parameter has been modified: a value of '99'
|
||||
now means that the recording will live "forever", and a value of '0' means
|
||||
that the recording has no guaranteed lifetime and will be deleted whenever
|
||||
a new recording with higher priority needs disk space.
|
||||
- Updated version of Matthias Schniedermeyer's 'schnitt' tools.
|
||||
- New 'master-timer' tool (thanks to Matthias Schniedermeyer).
|
||||
|
11
MANUAL
11
MANUAL
@ -32,11 +32,11 @@ Video Disk Recorder User's Manual
|
||||
confirms any changes (or switches to a channel in the "Channels" menu).
|
||||
The "Back" key goes back one level in the menu structure, discarding
|
||||
any changes that might have been made in the current menu.
|
||||
|
||||
|
||||
In the "Timers" menu, the current timer can be enabled or disabled with
|
||||
the "Right" or "Left" key, respectively (enabled timers are marked with ">").
|
||||
"Ok" here opens the "Edit timer" menu.
|
||||
|
||||
|
||||
Textual options, like channel names or recording file names, can be edited
|
||||
by pressing the "Right" button (which puts brackets around the current
|
||||
character as in "[R]TL"), selecting the desired character position with
|
||||
@ -46,10 +46,10 @@ Video Disk Recorder User's Manual
|
||||
brackets (as in abc[^]), the next press to the "Left" or "Ok" button will
|
||||
actually cut off the string. Using "Up" and/or "Down" brings back the
|
||||
original rest of the string (unless you have pressed "Left" or "Ok").
|
||||
|
||||
|
||||
The "Red", "Green", "Yellow" and "Blue" buttons have special meanings
|
||||
in various menus and are listed at the bottom of the on-screen-display.
|
||||
|
||||
|
||||
At any point in the menu system, pressing the "Menu" key again will
|
||||
immediately leave the menu system (discarding any pending changes).
|
||||
|
||||
@ -309,7 +309,8 @@ Video Disk Recorder User's Manual
|
||||
0 = instant recordings will not be marked
|
||||
1 = instant recordings will be marked.
|
||||
|
||||
LnbFrequLo = 9750 The low and high LNB frequencies (in MHz)
|
||||
LnbSLOF = 11700 The switching frequency (in MHz) between low and high LOF
|
||||
LnbFrequLo = 9750 The LNB's low and high local oscillator frequencies (in MHz)
|
||||
LnbFrequHi = 10600 (these have no meaning for DVB-C receivers)
|
||||
|
||||
SetSystemTime = 0 Defines whether the system time will be set according to
|
||||
|
8
Makefile
8
Makefile
@ -4,11 +4,11 @@
|
||||
# See the main source file 'vdr.c' for copyright information and
|
||||
# how to reach the author.
|
||||
#
|
||||
# $Id: Makefile 1.21 2001/03/18 16:47:00 kls Exp $
|
||||
# $Id: Makefile 1.22 2001/06/02 09:15:39 kls Exp $
|
||||
|
||||
DVBDIR = ../DVB
|
||||
|
||||
INCLUDES = -I$(DVBDIR)/driver
|
||||
INCLUDES = -I$(DVBDIR)/ost/include
|
||||
OBJS = config.o dvbapi.o dvbosd.o eit.o font.o i18n.o interface.o menu.o osd.o\
|
||||
recording.o remote.o remux.o ringbuffer.o svdrp.o thread.o tools.o vdr.o\
|
||||
videodir.o
|
||||
@ -43,7 +43,7 @@ font: genfontfile fontfix.c fontosd.c
|
||||
# Dependencies:
|
||||
|
||||
config.o : config.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h remote.h svdrp.h thread.h tools.h
|
||||
dvbapi.o : dvbapi.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h recording.h remote.h remux.h ringbuffer.h svdrp.h thread.h tools.h videodir.h
|
||||
dvbapi.o : dvbapi.c config.h dvbapi.h dvbosd.h eit.h font.h recording.h remux.h ringbuffer.h thread.h tools.h videodir.h
|
||||
dvbosd.o : dvbosd.c dvbosd.h font.h tools.h
|
||||
eit.o : eit.c config.h dvbapi.h dvbosd.h eit.h font.h thread.h tools.h videodir.h
|
||||
font.o : font.c font.h fontfix.c fontosd.c tools.h
|
||||
@ -53,7 +53,7 @@ menu.o : menu.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h
|
||||
osd.o : osd.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h osd.h remote.h svdrp.h thread.h tools.h
|
||||
recording.o : recording.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h recording.h remote.h svdrp.h thread.h tools.h videodir.h
|
||||
remote.o : remote.c config.h dvbapi.h dvbosd.h eit.h font.h remote.h thread.h tools.h
|
||||
remux.o : remux.c remux.h tools.h
|
||||
remux.o : remux.c remux.h thread.h tools.h
|
||||
ringbuffer.o: ringbuffer.c ringbuffer.h thread.h tools.h
|
||||
svdrp.o : svdrp.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h
|
||||
thread.o : thread.c thread.h tools.h
|
||||
|
175
channels.conf
175
channels.conf
@ -1,175 +0,0 @@
|
||||
RTL:12188:h:0:27500:163:104:105:0:12003
|
||||
Sat.1:12480:v:0:27500:1791:1792:34:0:46
|
||||
Pro-7:12480:v:0:27500:255:256:32:0:898
|
||||
RTL2:12188:h:0:27500:166:128:68:0:12020
|
||||
ARD:11837:h:0:27500:101:102:0:0:28106
|
||||
BR3:11837:h:0:27500:201:202:0:0:28107
|
||||
Hessen-3:11837:h:0:27500:301:302:0:0:28108
|
||||
N3:12110:h:0:27500:2401:2402:0:0:28224
|
||||
SR3:11837:h:0:27500:501:502:0:0:28110
|
||||
WDR:11837:h:0:27500:601:602:0:0:28111
|
||||
BR-alpha:11837:h:0:27500:701:702:0:0:28112
|
||||
SWR BW:11837:h:0:27500:801:802:0:0:28113
|
||||
Phoenix:11837:h:0:27500:901:902:0:0:28114
|
||||
ZDF:11954:h:0:27500:110:120:130:0:28006
|
||||
3sat:11954:h:0:27500:210:220:230:0:28007
|
||||
KiKa:11954:h:0:27500:310:320:0:0:28008
|
||||
arte:11836:h:0:27500:401:402:0:0:28109
|
||||
ORF1:12692:h:0:22000:160:161:165:3:13001
|
||||
ORF2:12692:h:0:22000:500:501:505:3:13007
|
||||
ORF Sat:11954:h:0:27500:506:507:0:0:28010
|
||||
ZDF.info:11954:h:0:27500:610:620:0:0:28011
|
||||
CNN:12168:v:0:27500:165:100:0:0:28512
|
||||
Super RTL:12188:h:0:27500:165:120:65:0:12040
|
||||
VOX:12188:h:0:27500:167:136:0:0:12060
|
||||
DW TV:12363:v:0:27500:305:306:0:0:8905
|
||||
Kabel 1:12480:v:0:27500:511:512:33:0:899
|
||||
tm3:12480:v:0:27500:767:768:0:0:897
|
||||
DSF:12480:v:0:27500:1023:1024:0:0:900
|
||||
HOT:12480:v:0:27500:1279:1280:0:0:40
|
||||
Bloomberg TV Germany:12551:v:0:22000:162:99:0:0:12160
|
||||
BLOOMBERG TV:11817:v:0:27500:163:92:0:0:8004
|
||||
Bloomberg:12168:v:0:27500:167:112:0:0:12721
|
||||
Sky News:12552:v:0:22000:305:306:0:0:3995
|
||||
KinderNet:12574:h:0:22000:163:92:0:0:5020
|
||||
Alice:12610:v:0:22000:162:96:0:0:12200
|
||||
n-tv:12669:v:0:22000:162:96:55:0:12730
|
||||
Grand Tourisme:12670:v:0:22000:289:290:0:0:17300
|
||||
TW1:12692:h:0:22000:166:167:0:0:13013
|
||||
Eurosport:11954:h:0:27500:410:420:0:0:28009
|
||||
EinsExtra:12110:h:0:27500:101:102:0:0:28201
|
||||
EinsFestival:12110:h:0:27500:201:202:0:0:28202
|
||||
EinsMuXx:12110:h:0:27500:301:302:0:0:28203
|
||||
ZDF Theaterkanal:11954:h:0:27500:1110:1120:0:0:28016
|
||||
ZDF.doku:11954:h:0:27500:660:670:0:0:28014
|
||||
MDR:12110:h:0:27500:401:402:0:0:28204
|
||||
NICK-PARAMOUNT:12246:v:0:27500:167:108:0:0:29312
|
||||
ORB:12110:h:0:27500:501:502:0:0:28205
|
||||
B1:12110:h:0:27500:601:602:0:0:28206
|
||||
ARD Online-Kanal:12722:h:0:22000:8191:701:0:0:0
|
||||
:Premiere World
|
||||
Premiere World Promo:11798:h:0:27500:255:256:0:0:8
|
||||
Premiere:11798:h:0:27500:511:512:0:3:10
|
||||
Star Kino:11798:h:0:27500:767:768:0:3:9
|
||||
Cine Action:11798:h:0:27500:1023:1024:0:3:20
|
||||
Cine Comedy:11798:h:0:27500:1279:1280:0:3:29
|
||||
Sci Fantasy:11798:h:0:27500:1535:1536:0:3:41
|
||||
Romantic Movies:11797:h:0:27500:1791:1792:0:3:11
|
||||
Studio Universal:12090:v:0:27500:255:256:0:3:36
|
||||
13th Street:11797:h:0:27500:2303:2304:0:3:43
|
||||
Junior:12031:h:0:27500:255:256:0:3:19
|
||||
K-Toon:12032:h:0:27500:511:512:0:3:12
|
||||
Disney Channel:12090:v:0:27500:767:768:0:3:34
|
||||
Fox Kids:11797:h:0:27500:2559:2560:0:3:22
|
||||
Sunset:12031:h:0:27500:1023:1024:0:3:16
|
||||
Comedy:12031:h:0:27500:1279:1280:0:3:28
|
||||
Planet:12090:v:0:27500:1279:1280:0:3:13
|
||||
Discovery Channel:12031:h:0:27500:1791:1792:0:3:14
|
||||
Krimi&Co:12031:h:0:27500:1535:1536:0:3:23
|
||||
Filmpalast:11758:h:0:27500:2559:2560:0:3:516
|
||||
Heimatkanal:11758:h:0:27500:2815:2816:0:3:517
|
||||
Goldstar:11758:h:0:27500:3839:3840:0:3:518
|
||||
Classica:12031:h:0:27500:767:768:0:3:15
|
||||
Seasons:12090:v:0:27500:511:512:0:3:33
|
||||
Sport 1:11720:h:0:27500:255:256:0:3:17
|
||||
Sport 2:12070:h:0:27500:2047:2048:0:3:27
|
||||
Sport 3:12070:h:0:27500:2303:2304:0:3:18
|
||||
Sport 4:12070:h:0:27500:2559:2560:0:3:24
|
||||
Feed (F1 Boxengasse):11720:h:0:27500:2559:2560:0:3:242
|
||||
Feed (F1 Data):11720:h:0:27500:3071:3072:0:3:244
|
||||
Feed (F1 Multi):11720:h:0:27500:2815:2816:0:3:243
|
||||
Feed (F1 On Board):11720:h:0:27500:2303:2304:0:3:241
|
||||
Feed (F1 Verfolger):11720:h:0:27500:2047:2048:0:3:240
|
||||
Cinedom Deluxe:12070:h:0:27500:1279:1280:0:3:188
|
||||
Cinedom 1A de:11758:h:0:27500:511:512:0:3:178
|
||||
Cinedom 1A en:11758:h:0:27500:511:513:0:3:178
|
||||
Cinedom 1B:12070:h:0:27500:767:768:0:3:185
|
||||
Cinedom 1C:12070:h:0:27500:1791:1792:0:3:191
|
||||
Cinedom 1E??:11720:h:0:27500:1535:1537:0:3:176
|
||||
Cinedom 2A:12070:h:0:27500:1535:1536:0:3:189
|
||||
Cinedom 2B:11758:h:0:27500:767:768:0:3:179
|
||||
Cinedom 2C:11758:h:0:27500:1023:1024:0:3:193
|
||||
Cinedom 2D??:12070:h:0:27500:511:512:0:3:184
|
||||
Cinedom 3A:11758:h:0:27500:255:256:0:3:177
|
||||
Cinedom 3B:11758:h:0:27500:1279:1280:0:3:194
|
||||
Cinedom 3C??:12090:v:0:27500:1279:1280:17689:3:192
|
||||
Cinedom 4A:11758:h:0:27500:1535:1536:0:3:195
|
||||
Cinedom 4B:12070:h:0:27500:1023:1025:0:3:186
|
||||
Cinedom 4C??:11720:h:0:27500:767:768:0:3:181
|
||||
Cinedom 5A:12032:h:0:27500:2559:2560:0:3:187
|
||||
Beate Uhse_TV:11797:h:0:27500:2047:2048:0:3:21
|
||||
Blue Channel:11758:h:0:27500:2559:2560:0:3:516
|
||||
Blue Movie 1:11758:h:0:27500:1791:1792:0:3:513
|
||||
Blue Movie 2:11758:h:0:27500:2047:2048:0:3:514
|
||||
Blue Movie 3:11758:h:0:27500:2303:2304:0:3:515
|
||||
:
|
||||
TV Niepokalanow:11876:h:0:27500:305:321:0:0:20601
|
||||
Mosaico:11934:v:0:27500:165:100:0:0:29010
|
||||
Andalucia TV:11934:v:0:27500:166:104:0:0:29011
|
||||
TVC Internacional:11934:v:0:27500:167:108:0:0:0
|
||||
Nasza TV:11992:h:0:27500:165:98:0:0:0
|
||||
WishLine test:12012:v:0:27500:163:90:0:0:0
|
||||
Pro 7 Austria:12051:v:0:27500:161:84:0:0:0
|
||||
Kabel 1 Schweiz:12051:v:0:27500:162:163:0:0:0
|
||||
Kabel 1 Austria:12051:v:0:27500:166:167:0:0:0
|
||||
Pro 7 Schweiz:12051:v:0:27500:289:290:0:0:0
|
||||
Kiosque:12129:v:0:27500:160:80:0:0:0
|
||||
KTO:12129:v:0:27500:170:120:0:0:0
|
||||
TCM:12168:v:0:27500:160:80:0:0:0
|
||||
Cartoon Network France & Spain:12168:v:0:27500:161:84:0:0:0
|
||||
TVBS Europe:12168:v:0:27500:162:88:0:0:0
|
||||
TVBS Europe:12168:v:0:27500:162:89:0:0:0
|
||||
Travel:12168:v:0:27500:163:92:0:0:0
|
||||
TCM Espania:12168:v:0:27500:164:96:0:0:0
|
||||
MTV Spain:12168:v:0:27500:167:112:0:0:0
|
||||
TCM France:12168:v:0:27500:169:64:0:0:0
|
||||
RTL2 CH:12188:h:0:27500:164:112:0:0:0
|
||||
La Cinquieme:12207:v:0:27500:160:80:0:0:0
|
||||
ARTE:12207:v:0:27500:165:100:0:0:0
|
||||
Post Filial TV:12226:h:0:27500:255:256:0:0:0
|
||||
Canal Canaris:12246:v:0:27500:160:80:0:0:0
|
||||
Canal Canaris:12246:v:0:27500:160:81:0:0:0
|
||||
Canal Canaris:12246:v:0:27500:160:82:0:0:0
|
||||
Canal Canaris:12246:v:0:27500:160:83:0:0:0
|
||||
AB Sat Passion promo:12266:h:0:27500:160:80:0:0:0
|
||||
AB Channel 1:12266:h:0:27500:161:84:0:0:0
|
||||
Taquilla 0:12285:v:0:27500:165:100:0:0:0
|
||||
CSAT:12324:v:0:27500:160:80:0:0:0
|
||||
Mosaique:12324:v:0:27500:162:88:0:0:0
|
||||
Mosaique 2:12324:v:0:27500:163:92:0:0:0
|
||||
Mosaique 3:12324:v:0:27500:164:96:0:0:0
|
||||
Le Sesame C+:12324:v:0:27500:165:1965:0:0:0
|
||||
FEED:12344:h:0:27500:163:92:0:0:0
|
||||
RTM 1:12363:v:0:27500:162:96:0:0:0
|
||||
ESC 1:12363:v:0:27500:163:104:0:0:0
|
||||
TV5 Europe:12363:v:0:27500:164:112:0:0:0
|
||||
TV7 Tunisia:12363:v:0:27500:166:128:0:0:0
|
||||
ARTE:12363:v:0:27500:167:137:0:0:0
|
||||
RAI Uno:12363:v:0:27500:289:290:0:0:8904
|
||||
RTP International:12363:v:0:27500:300:301:0:0:0
|
||||
Fashion TV:12402:v:0:27500:163:92:0:0:0
|
||||
VideoService:12422:h:0:27500:255:256:0:0:0
|
||||
Beta Research promo:12422:h:0:27500:1023:1024:0:0:0
|
||||
Canal Canarias:12441:v:0:27500:160:80:0:0:0
|
||||
TVC International:12441:v:0:27500:512:660:0:0:0
|
||||
Fitur:12441:v:0:27500:514:662:0:0:0
|
||||
Astra Info 1:12552:v:0:22000:164:112:0:0:0
|
||||
Astra Info 2:12552:v:0:22000:165:120:0:0:0
|
||||
Astra Vision 1:12552:v:0:22000:168:144:0:0:0
|
||||
Astra Vision 1:12552:v:0:22000:168:145:0:0:0
|
||||
Astra Vision 1:12552:v:0:22000:168:146:0:0:0
|
||||
Astra Vision 1:12552:v:0:22000:168:147:0:0:0
|
||||
Astra Vision 1:12552:v:0:22000:168:148:0:0:0
|
||||
Astra Vision 1:12552:v:0:22000:168:149:0:0:0
|
||||
Astra Vision 1:12552:v:0:22000:168:150:0:0:0
|
||||
RTL Tele Letzebuerg:12552:v:0:22000:168:144:0:0:0
|
||||
Astra Mosaic:12552:v:0:22000:175:176:0:0:0
|
||||
MHP test:12604:h:0:22000:5632:8191:0:0:0
|
||||
VERONICA:12574:h:0:22000:161:84:0:0:5010
|
||||
VH1 Classic:12699:v:0:22000:3071:3072:0:0:28647
|
||||
VH-1 Germany:12699:v:0:22000:3081:3082:0:0:28648
|
||||
Via 1 - Schöner Reisen:12148:h:0:27500:511:512:0:0:44
|
||||
Video Italia:12610:v:0:22000:121:122:0:0:12220
|
||||
AC 3 promo:12670:v:0:22000:308:256:0:0:0
|
||||
ORF/ZDF:12699:h:0:22000:506:507:0:0:13012
|
||||
VIVA:12670:v:0:22000:309:310:0:0:12732
|
27
config.c
27
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 1.44 2001/04/01 14:32:22 kls Exp $
|
||||
* $Id: config.c 1.45 2001/06/02 09:42:25 kls Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -155,7 +155,7 @@ eKeys cKeys::Get(unsigned int Code)
|
||||
}
|
||||
|
||||
eKeys cKeys::Translate(const char *Command)
|
||||
{
|
||||
{
|
||||
if (Command) {
|
||||
const tKey *k = keys;
|
||||
while ((k->type != kNone) && strcasecmp(k->name, Command) != 0)
|
||||
@ -166,7 +166,7 @@ eKeys cKeys::Translate(const char *Command)
|
||||
}
|
||||
|
||||
unsigned int cKeys::Encode(const char *Command)
|
||||
{
|
||||
{
|
||||
eKeys k = Translate(Command);
|
||||
if (k != kNone)
|
||||
return keys[k].code;
|
||||
@ -305,8 +305,8 @@ cTimer::cTimer(bool Instant)
|
||||
if (stop >= 2400)
|
||||
stop -= 2400;
|
||||
//TODO VPS???
|
||||
priority = DEFAULTPRIORITY;
|
||||
lifetime = DEFAULTLIFETIME;
|
||||
priority = Setup.DefaultPriority;
|
||||
lifetime = Setup.DefaultLifetime;
|
||||
*file = 0;
|
||||
summary = NULL;
|
||||
if (Instant && ch)
|
||||
@ -330,8 +330,8 @@ cTimer::cTimer(const cEventInfo *EventInfo)
|
||||
stop = time->tm_hour * 100 + time->tm_min;
|
||||
if (stop >= 2400)
|
||||
stop -= 2400;
|
||||
priority = DEFAULTPRIORITY;
|
||||
lifetime = DEFAULTLIFETIME;
|
||||
priority = Setup.DefaultPriority;
|
||||
lifetime = Setup.DefaultLifetime;
|
||||
*file = 0;
|
||||
const char *Title = EventInfo->GetTitle();
|
||||
if (!isempty(Title))
|
||||
@ -524,14 +524,14 @@ bool cTimer::Matches(time_t t)
|
||||
}
|
||||
|
||||
time_t cTimer::StartTime(void)
|
||||
{
|
||||
{
|
||||
if (!startTime)
|
||||
Matches();
|
||||
return startTime;
|
||||
}
|
||||
|
||||
time_t cTimer::StopTime(void)
|
||||
{
|
||||
{
|
||||
if (!stopTime)
|
||||
Matches();
|
||||
return stopTime;
|
||||
@ -734,6 +734,7 @@ cSetup::cSetup(void)
|
||||
ShowInfoOnChSwitch = 1;
|
||||
MenuScrollPage = 1;
|
||||
MarkInstantRecord = 1;
|
||||
LnbSLOF = 11700;
|
||||
LnbFrequLo = 9750;
|
||||
LnbFrequHi = 10600;
|
||||
SetSystemTime = 0;
|
||||
@ -742,6 +743,8 @@ cSetup::cSetup(void)
|
||||
EPGScanTimeout = 5;
|
||||
SVDRPTimeout = 300;
|
||||
PrimaryLimit = 0;
|
||||
DefaultPriority = 50;
|
||||
DefaultLifetime = 50;
|
||||
CurrentChannel = -1;
|
||||
}
|
||||
|
||||
@ -756,6 +759,7 @@ bool cSetup::Parse(char *s)
|
||||
else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value);
|
||||
else if (!strcasecmp(Name, "MenuScrollPage")) MenuScrollPage = atoi(Value);
|
||||
else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value);
|
||||
else if (!strcasecmp(Name, "LnbSLOF")) LnbSLOF = atoi(Value);
|
||||
else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value);
|
||||
else if (!strcasecmp(Name, "LnbFrequHi")) LnbFrequHi = atoi(Value);
|
||||
else if (!strcasecmp(Name, "SetSystemTime")) SetSystemTime = atoi(Value);
|
||||
@ -764,6 +768,8 @@ bool cSetup::Parse(char *s)
|
||||
else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value);
|
||||
else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value);
|
||||
else if (!strcasecmp(Name, "PrimaryLimit")) PrimaryLimit = atoi(Value);
|
||||
else if (!strcasecmp(Name, "DefaultPriority")) DefaultPriority = atoi(Value);
|
||||
else if (!strcasecmp(Name, "DefaultLifetime")) DefaultLifetime = atoi(Value);
|
||||
else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value);
|
||||
else
|
||||
return false;
|
||||
@ -813,6 +819,7 @@ bool cSetup::Save(const char *FileName)
|
||||
fprintf(f, "ShowInfoOnChSwitch = %d\n", ShowInfoOnChSwitch);
|
||||
fprintf(f, "MenuScrollPage = %d\n", MenuScrollPage);
|
||||
fprintf(f, "MarkInstantRecord = %d\n", MarkInstantRecord);
|
||||
fprintf(f, "LnbSLOF = %d\n", LnbSLOF);
|
||||
fprintf(f, "LnbFrequLo = %d\n", LnbFrequLo);
|
||||
fprintf(f, "LnbFrequHi = %d\n", LnbFrequHi);
|
||||
fprintf(f, "SetSystemTime = %d\n", SetSystemTime);
|
||||
@ -821,6 +828,8 @@ bool cSetup::Save(const char *FileName)
|
||||
fprintf(f, "EPGScanTimeout = %d\n", EPGScanTimeout);
|
||||
fprintf(f, "SVDRPTimeout = %d\n", SVDRPTimeout);
|
||||
fprintf(f, "PrimaryLimit = %d\n", PrimaryLimit);
|
||||
fprintf(f, "DefaultPriority = %d\n", DefaultPriority);
|
||||
fprintf(f, "DefaultLifetime = %d\n", DefaultLifetime);
|
||||
fprintf(f, "CurrentChannel = %d\n", CurrentChannel);
|
||||
f.Close();
|
||||
isyslog(LOG_INFO, "saved setup to %s", FileName);
|
||||
|
14
config.h
14
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 1.44 2001/04/01 14:44:40 kls Exp $
|
||||
* $Id: config.h 1.45 2001/06/02 09:43:04 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
@ -19,10 +19,13 @@
|
||||
#include "eit.h"
|
||||
#include "tools.h"
|
||||
|
||||
#define VDRVERSION "0.72"
|
||||
#define VDRVERSION "0.80"
|
||||
|
||||
#define MaxBuffer 10000
|
||||
|
||||
#define MAXPRIORITY 99
|
||||
#define MAXLIFETIME 99
|
||||
|
||||
enum eKeys { // "Up" and "Down" must be the first two keys!
|
||||
kUp,
|
||||
kDown,
|
||||
@ -106,9 +109,6 @@ public:
|
||||
bool Switch(cDvbApi *DvbApi = NULL, bool Log = true);
|
||||
};
|
||||
|
||||
#define DEFAULTPRIORITY 99
|
||||
#define DEFAULTLIFETIME 99
|
||||
|
||||
class cTimer : public cListObject {
|
||||
private:
|
||||
time_t startTime, stopTime;
|
||||
@ -240,7 +240,7 @@ public:
|
||||
bool SwitchTo(int Number, cDvbApi *DvbApi = NULL);
|
||||
int MaxNumber(void) { return maxNumber; }
|
||||
};
|
||||
|
||||
|
||||
class cTimers : public cConfig<cTimer> {
|
||||
public:
|
||||
cTimer *GetTimer(cTimer *Timer);
|
||||
@ -266,6 +266,7 @@ public:
|
||||
int ShowInfoOnChSwitch;
|
||||
int MenuScrollPage;
|
||||
int MarkInstantRecord;
|
||||
int LnbSLOF;
|
||||
int LnbFrequLo;
|
||||
int LnbFrequHi;
|
||||
int SetSystemTime;
|
||||
@ -273,6 +274,7 @@ public:
|
||||
int EPGScanTimeout;
|
||||
int SVDRPTimeout;
|
||||
int PrimaryLimit;
|
||||
int DefaultPriority, DefaultLifetime;
|
||||
int CurrentChannel;
|
||||
cSetup(void);
|
||||
bool Load(const char *FileName);
|
||||
|
47
dvbapi.h
47
dvbapi.h
@ -4,22 +4,28 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: dvbapi.h 1.35 2001/02/11 10:41:10 kls Exp $
|
||||
* $Id: dvbapi.h 1.36 2001/06/02 09:44:00 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __DVBAPI_H
|
||||
#define __DVBAPI_H
|
||||
|
||||
// FIXME: these should be defined in ../DVB/driver/dvb.h!!!
|
||||
typedef unsigned int __u32;
|
||||
typedef unsigned short __u16;
|
||||
typedef unsigned char __u8;
|
||||
|
||||
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
||||
#include <ncurses.h>
|
||||
#endif
|
||||
#include <stdlib.h> // FIXME: this is apparently necessary for the ost/... header files
|
||||
// FIXME: shouldn't every header file include ALL the other header
|
||||
// FIXME: files it depends on? The sequence in which header files
|
||||
// FIXME: are included here should not matter - and it should NOT
|
||||
// FIXME: be necessary to include <stdlib.h> here!
|
||||
#include <linux/videodev.h>
|
||||
#include <ost/dmx.h>
|
||||
#include <ost/sec.h>
|
||||
#include <ost/frontend.h>
|
||||
#include <ost/video.h>
|
||||
#include <ost/audio.h>
|
||||
#include <ost/osd.h>
|
||||
#include <stdio.h>
|
||||
#include <dvb.h>
|
||||
#include "dvbosd.h"
|
||||
#include "eit.h"
|
||||
#include "thread.h"
|
||||
@ -30,7 +36,7 @@ typedef struct CRect {
|
||||
signed short x, y, width, height;
|
||||
};
|
||||
|
||||
#define MenuLines 15
|
||||
#define MenuLines 13 // XXX originally 15, but since driver version 2001-05-25 there is less OSD memory :-(
|
||||
#define MenuColumns 40
|
||||
|
||||
const char *IndexToHMSF(int Index, bool WithFrame = false);
|
||||
@ -55,9 +61,19 @@ public:
|
||||
};
|
||||
|
||||
class cDvbApi {
|
||||
friend class cRecordBuffer;
|
||||
friend class cReplayBuffer;
|
||||
friend class cTransferBuffer;
|
||||
private:
|
||||
int videoDev;
|
||||
cDvbApi(const char *VideoFileName, const char *VbiFileName);
|
||||
int fd_osd, fd_qpskfe, fd_qamfe, fd_sec, fd_dvr, fd_audio, fd_video, fd_demuxa, fd_demuxv, fd_demuxt;
|
||||
int vPid, aPid;
|
||||
bool SetPid(int fd, dmxPesType_t PesType, dvb_pid_t Pid, dmxOutput_t Output);
|
||||
bool SetVpid(int Vpid, dmxOutput_t Output) { return SetPid(fd_demuxv, DMX_PES_VIDEO, Vpid, Output); }
|
||||
bool SetApid(int Apid, dmxOutput_t Output) { return SetPid(fd_demuxa, DMX_PES_AUDIO, Apid, Output); }
|
||||
bool SetTpid(int Tpid, dmxOutput_t Output) { return SetPid(fd_demuxt, DMX_PES_TELETEXT, Tpid, Output); }
|
||||
bool SetPids(bool ForRecording);
|
||||
cDvbApi(int n);
|
||||
public:
|
||||
~cDvbApi();
|
||||
|
||||
@ -86,8 +102,10 @@ public:
|
||||
// recording and stop recording if necessary.
|
||||
int Index(void);
|
||||
// Returns the index of this DvbApi.
|
||||
static bool Probe(const char *FileName);
|
||||
// Probes for existing DVB devices.
|
||||
static bool Init(void);
|
||||
// Initializes the DVB API and probes for existing DVB devices.
|
||||
// Initializes the DVB API.
|
||||
// Must be called before accessing any DVB functions.
|
||||
static void Cleanup(void);
|
||||
// Closes down all DVB devices.
|
||||
@ -184,12 +202,15 @@ private:
|
||||
cReplayBuffer *replayBuffer;
|
||||
int ca;
|
||||
int priority;
|
||||
protected:
|
||||
int Ca(void) { return ca; }
|
||||
// Returns the ca of the current recording session (0..MAXDVBAPI).
|
||||
int Priority(void) { return priority; }
|
||||
// Returns the priority of the current recording session (0..99),
|
||||
// Returns the priority of the current recording session (0..MAXPRIORITY),
|
||||
// or -1 if no recording is currently active.
|
||||
int SetModeRecord(void);
|
||||
// Initiates recording mode and returns the file handle to read from.
|
||||
void SetModeReplay(void);
|
||||
void SetModeNormal(bool FromRecording);
|
||||
public:
|
||||
int SecondsToFrames(int Seconds);
|
||||
// Returns the number of frames corresponding to the given number of seconds.
|
||||
@ -238,7 +259,7 @@ public:
|
||||
// nearest I-frame.
|
||||
void Goto(int Index, bool Still = false);
|
||||
// Positions to the given index and displays that frame as a still picture
|
||||
// if Still is true.
|
||||
// if Still is true.
|
||||
};
|
||||
|
||||
class cEITScanner {
|
||||
|
6
dvbosd.c
6
dvbosd.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: dvbosd.c 1.7 2000/12/09 11:13:00 kls Exp $
|
||||
* $Id: dvbosd.c 1.8 2001/05/26 11:49:35 kls Exp $
|
||||
*/
|
||||
|
||||
#include "dvbosd.h"
|
||||
@ -157,7 +157,7 @@ cDvbOsd::~cDvbOsd()
|
||||
void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data)
|
||||
{
|
||||
if (videoDev >= 0) {
|
||||
struct drawcmd dc;
|
||||
osd_cmd_t dc;
|
||||
dc.cmd = cmd;
|
||||
dc.color = color;
|
||||
dc.x0 = x0;
|
||||
@ -169,7 +169,7 @@ void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, co
|
||||
sigset_t set, oldset;
|
||||
sigfillset(&set);
|
||||
sigprocmask(SIG_BLOCK, &set, &oldset);
|
||||
ioctl(videoDev, VIDIOCSOSDCOMMAND, &dc);
|
||||
ioctl(videoDev, OSD_SEND_CMD, &dc);
|
||||
usleep(10); // XXX Workaround for a driver bug (cInterface::DisplayChannel() displayed texts at wrong places
|
||||
// XXX and sometimes the OSD was no longer displayed).
|
||||
// XXX Increase the value if the problem still persists on your particular system.
|
||||
|
6
dvbosd.h
6
dvbosd.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: dvbosd.h 1.5 2000/12/09 10:32:47 kls Exp $
|
||||
* $Id: dvbosd.h 1.6 2001/05/01 14:41:42 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __DVBOSD_H
|
||||
@ -18,11 +18,11 @@ typedef unsigned char __u8;
|
||||
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
||||
#include <ncurses.h>
|
||||
#endif
|
||||
#include <ost/osd.h>
|
||||
#include <stdio.h>
|
||||
#include <dvb.h>
|
||||
#include "font.h"
|
||||
|
||||
enum eDvbColor {
|
||||
enum eDvbColor {
|
||||
#ifndef DEBUG_OSD
|
||||
clrTransparent,
|
||||
#endif
|
||||
|
263
eit.c
263
eit.c
@ -13,17 +13,16 @@
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* $Id: eit.c 1.15 2001/04/01 15:36:09 kls Exp $
|
||||
* $Id: eit.c 1.16 2001/05/26 10:58:01 kls Exp $
|
||||
***************************************************************************/
|
||||
|
||||
#include "eit.h"
|
||||
#include <ctype.h>
|
||||
#include <dvb_comcode.h>
|
||||
#include <dvb_v4l.h>
|
||||
#include <fcntl.h>
|
||||
#include <fstream.h>
|
||||
#include <iomanip.h>
|
||||
#include <iostream.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -1108,31 +1107,43 @@ cMutex cSIProcessor::schedulesMutex;
|
||||
/** */
|
||||
cSIProcessor::cSIProcessor(const char *FileName)
|
||||
{
|
||||
fileName = strdup(FileName);
|
||||
masterSIProcessor = numSIProcessors == 0; // the first one becomes the 'master'
|
||||
useTStime = false;
|
||||
filters = NULL;
|
||||
if ((fsvbi = open(FileName, O_RDONLY)) >= 0)
|
||||
{
|
||||
if (!numSIProcessors++) // the first one creates it
|
||||
schedules = new cSchedules;
|
||||
filters = (SIP_FILTER *)calloc(MAX_FILTERS, sizeof(SIP_FILTER));
|
||||
}
|
||||
else
|
||||
LOG_ERROR_STR(FileName);
|
||||
if (!numSIProcessors++) // the first one creates it
|
||||
schedules = new cSchedules;
|
||||
filters = (SIP_FILTER *)calloc(MAX_FILTERS, sizeof(SIP_FILTER));
|
||||
SetStatus(true);
|
||||
Start();
|
||||
}
|
||||
|
||||
cSIProcessor::~cSIProcessor()
|
||||
{
|
||||
if (fsvbi >= 0)
|
||||
active = false;
|
||||
Cancel(3);
|
||||
ShutDownFilters();
|
||||
delete filters;
|
||||
if (!--numSIProcessors) // the last one deletes it
|
||||
delete schedules;
|
||||
delete fileName;
|
||||
}
|
||||
|
||||
void cSIProcessor::SetStatus(bool On)
|
||||
{
|
||||
LOCK_THREAD;
|
||||
schedulesMutex.Lock();
|
||||
ShutDownFilters();
|
||||
if (On)
|
||||
{
|
||||
active = false;
|
||||
Cancel(3);
|
||||
ShutDownFilters();
|
||||
delete filters;
|
||||
if (!--numSIProcessors) // the last one deletes it
|
||||
delete schedules;
|
||||
close(fsvbi);
|
||||
AddFilter(0x14, 0x70); // TDT
|
||||
AddFilter(0x14, 0x73); // TOT
|
||||
AddFilter(0x12, 0x4e); // event info, actual TS, present/following
|
||||
AddFilter(0x12, 0x4f); // event info, other TS, present/following
|
||||
AddFilter(0x12, 0x50); // event info, actual TS, schedule
|
||||
AddFilter(0x12, 0x60); // event info, other TS, schedule
|
||||
}
|
||||
schedulesMutex.Unlock();
|
||||
}
|
||||
|
||||
/** use the vbi device to parse all relevant SI
|
||||
@ -1140,19 +1151,10 @@ information and let the classes corresponding
|
||||
to the tables write their information to the disk */
|
||||
void cSIProcessor::Action()
|
||||
{
|
||||
if (fsvbi < 0) {
|
||||
esyslog(LOG_ERR, "cSIProcessor::Action() called without open file - returning");
|
||||
return;
|
||||
}
|
||||
|
||||
dsyslog(LOG_INFO, "EIT processing thread started (pid=%d)%s", getpid(), masterSIProcessor ? " - master" : "");
|
||||
|
||||
unsigned char buf[4096+1]; // max. allowed size for any EIT section (+1 for safety ;-)
|
||||
unsigned int seclen;
|
||||
unsigned int pid;
|
||||
time_t lastCleanup = time(NULL);
|
||||
time_t lastDump = time(NULL);
|
||||
struct pollfd pfd;
|
||||
|
||||
active = true;
|
||||
|
||||
@ -1187,100 +1189,123 @@ void cSIProcessor::Action()
|
||||
}
|
||||
}
|
||||
|
||||
/* wait data become ready from the bitfilter */
|
||||
pfd.fd = fsvbi;
|
||||
pfd.events = POLLIN;
|
||||
if(poll(&pfd, 1, 1000) != 0) /* timeout is 5 secs */
|
||||
// set up pfd structures for all active filter
|
||||
pollfd pfd[MAX_FILTERS];
|
||||
int NumUsedFilters = 0;
|
||||
for (int a = 0; a < MAX_FILTERS ; a++)
|
||||
{
|
||||
// fprintf(stderr, "<data>\n");
|
||||
/* read section */
|
||||
read(fsvbi, buf, 8);
|
||||
seclen = (buf[6] << 8) | buf[7];
|
||||
pid = (buf[4] << 8) | buf[5];
|
||||
read(fsvbi, buf, seclen);
|
||||
|
||||
//dsyslog(LOG_INFO, "Received pid 0x%02x with table ID 0x%02x and length of %04d\n", pid, buf[0], seclen);
|
||||
|
||||
switch (pid)
|
||||
if (filters[a].inuse)
|
||||
{
|
||||
case 0x14:
|
||||
if (buf[0] == 0x70)
|
||||
{
|
||||
if (useTStime)
|
||||
{
|
||||
cTDT ctdt((tdt_t *)buf);
|
||||
ctdt.SetSystemTime();
|
||||
}
|
||||
}
|
||||
/*XXX this comes pretty often:
|
||||
else
|
||||
dsyslog(LOG_INFO, "Time packet was not 0x70 but 0x%02x\n", (int)buf[0]);
|
||||
XXX*/
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
if (buf[0] != 0x72)
|
||||
{
|
||||
LOCK_THREAD;
|
||||
|
||||
schedulesMutex.Lock();
|
||||
cEIT ceit(buf, seclen, schedules);
|
||||
ceit.ProcessEIT();
|
||||
schedulesMutex.Unlock();
|
||||
}
|
||||
else
|
||||
dsyslog(LOG_INFO, "Received stuffing section in EIT\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
pfd[NumUsedFilters].fd = filters[a].handle;
|
||||
pfd[NumUsedFilters].events = POLLIN;
|
||||
NumUsedFilters++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCK_THREAD;
|
||||
|
||||
//XXX this comes pretty often
|
||||
//isyslog(LOG_INFO, "Received timeout from poll, refreshing filters\n");
|
||||
RefreshFilters();
|
||||
// wait until data becomes ready from the bitfilter
|
||||
if (poll(pfd, NumUsedFilters, 1000) != 0)
|
||||
{
|
||||
for (int a = 0; a < NumUsedFilters ; a++)
|
||||
{
|
||||
if (pfd[a].revents & POLLIN)
|
||||
{
|
||||
/* read section */
|
||||
unsigned char buf[4096+1]; // max. allowed size for any EIT section (+1 for safety ;-)
|
||||
if (read(filters[a].handle, buf, 3) == 3)
|
||||
{
|
||||
int seclen = ((buf[1] & 0x0F) << 8) | (buf[2] & 0xFF);
|
||||
int pid = filters[a].pid;
|
||||
int n = read(filters[a].handle, buf + 3, seclen);
|
||||
if (n == seclen)
|
||||
{
|
||||
seclen += 3;
|
||||
//dsyslog(LOG_INFO, "Received pid 0x%02x with table ID 0x%02x and length of %04d\n", pid, buf[0], seclen);
|
||||
switch (pid)
|
||||
{
|
||||
case 0x14:
|
||||
if (buf[0] == 0x70)
|
||||
{
|
||||
if (useTStime)
|
||||
{
|
||||
cTDT ctdt((tdt_t *)buf);
|
||||
ctdt.SetSystemTime();
|
||||
}
|
||||
}
|
||||
/*XXX this comes pretty often:
|
||||
else
|
||||
dsyslog(LOG_INFO, "Time packet was not 0x70 but 0x%02x\n", (int)buf[0]);
|
||||
XXX*/
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
if (buf[0] != 0x72)
|
||||
{
|
||||
LOCK_THREAD;
|
||||
|
||||
schedulesMutex.Lock();
|
||||
cEIT ceit(buf, seclen, schedules);
|
||||
ceit.ProcessEIT();
|
||||
schedulesMutex.Unlock();
|
||||
}
|
||||
else
|
||||
dsyslog(LOG_INFO, "Received stuffing section in EIT\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
dsyslog(LOG_INFO, "read incomplete section - seclen = %d, n = %d", seclen, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// WakeUp();
|
||||
}
|
||||
|
||||
dsyslog(LOG_INFO, "EIT processing thread ended (pid=%d)%s", getpid(), masterSIProcessor ? " - master" : "");
|
||||
}
|
||||
|
||||
/** Add a filter with packet identifier pid and
|
||||
table identifer tid */
|
||||
bool cSIProcessor::AddFilter(u_char pid, u_char tid)
|
||||
{
|
||||
if (fsvbi < 0)
|
||||
return false;
|
||||
|
||||
int section = ((int)tid << 8) | 0x00ff;
|
||||
|
||||
struct bitfilter filt = {
|
||||
pid,
|
||||
{ section, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
|
||||
SECTION_CONTINUOS, 0,
|
||||
FILTER_MEM,
|
||||
{},
|
||||
};
|
||||
|
||||
if (ioctl(fsvbi, VIDIOCSBITFILTER, &filt) < 0)
|
||||
return false;
|
||||
dmxSctFilterParams sctFilterParams;
|
||||
sctFilterParams.pid = pid;
|
||||
memset(&sctFilterParams.filter.filter, 0, DMX_FILTER_SIZE);
|
||||
memset(&sctFilterParams.filter.mask, 0, DMX_FILTER_SIZE);
|
||||
sctFilterParams.timeout = 0;
|
||||
sctFilterParams.flags = DMX_IMMEDIATE_START;
|
||||
sctFilterParams.filter.filter[0] = tid;
|
||||
sctFilterParams.filter.mask[0] = 0xFF;
|
||||
|
||||
for (int a = 0; a < MAX_FILTERS; a++)
|
||||
{
|
||||
if (filters[a].inuse == false)
|
||||
if (!filters[a].inuse)
|
||||
{
|
||||
filters[a].pid = pid;
|
||||
filters[a].tid = tid;
|
||||
filters[a].handle = filt.handle;
|
||||
filters[a].inuse = true;
|
||||
// dsyslog(LOG_INFO, " Registered filter handle %04x, pid = %02d, tid = %02d", filters[a].handle, filters[a].pid, filters[a].tid);
|
||||
if ((filters[a].handle = open(fileName, O_RDWR | O_NONBLOCK)) >= 0)
|
||||
{
|
||||
if (ioctl(filters[a].handle, DMX_SET_FILTER, &sctFilterParams) >= 0)
|
||||
filters[a].inuse = true;
|
||||
else
|
||||
{
|
||||
esyslog(LOG_ERR, "ERROR: can't set filter");
|
||||
close(filters[a].handle);
|
||||
return false;
|
||||
}
|
||||
// dsyslog(LOG_INFO, " Registered filter handle %04x, pid = %02d, tid = %02d", filters[a].handle, filters[a].pid, filters[a].tid);
|
||||
}
|
||||
else
|
||||
{
|
||||
esyslog(LOG_ERR, "ERROR: can't open filter handle");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
esyslog(LOG_ERR, "ERROR: too many filters");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -1294,27 +1319,19 @@ bool cSIProcessor::SetUseTSTime(bool use)
|
||||
}
|
||||
|
||||
/** */
|
||||
bool cSIProcessor::ShutDownFilters()
|
||||
bool cSIProcessor::ShutDownFilters(void)
|
||||
{
|
||||
if (fsvbi < 0)
|
||||
return false;
|
||||
|
||||
bool ret = true;
|
||||
|
||||
for (int a = 0; a < MAX_FILTERS; a++)
|
||||
{
|
||||
if (filters[a].inuse == true)
|
||||
if (filters[a].inuse)
|
||||
{
|
||||
if (ioctl(fsvbi, VIDIOCSSHUTDOWNFILTER, &filters[a].handle) < 0)
|
||||
ret = false;
|
||||
|
||||
close(filters[a].handle);
|
||||
// dsyslog(LOG_INFO, "Deregistered filter handle %04x, pid = %02d, tid = %02d", filters[a].handle, filters[a].pid, filters[a].tid);
|
||||
|
||||
filters[a].inuse = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return true; // there's no real 'boolean' to return here...
|
||||
}
|
||||
|
||||
/** */
|
||||
@ -1323,25 +1340,3 @@ bool cSIProcessor::SetCurrentServiceID(unsigned short servid)
|
||||
LOCK_THREAD;
|
||||
return schedules ? schedules->SetCurrentServiceID(servid) : false;
|
||||
}
|
||||
|
||||
/** */
|
||||
bool cSIProcessor::RefreshFilters()
|
||||
{
|
||||
if (fsvbi < 0)
|
||||
return false;
|
||||
|
||||
bool ret = true;
|
||||
|
||||
ret = ShutDownFilters();
|
||||
|
||||
for (int a = 0; a < MAX_FILTERS; a++)
|
||||
{
|
||||
if (filters[a].inuse == false && filters[a].pid != 0 && filters[a].tid != 0)
|
||||
{
|
||||
if (!AddFilter(filters[a].pid, filters[a].tid))
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
10
eit.h
10
eit.h
@ -13,7 +13,7 @@
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* $Id: eit.h 1.6 2001/04/01 15:14:12 kls Exp $
|
||||
* $Id: eit.h 1.7 2001/05/25 12:56:53 kls Exp $
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __EIT_H
|
||||
@ -129,16 +129,16 @@ private:
|
||||
bool masterSIProcessor;
|
||||
bool useTStime;
|
||||
SIP_FILTER *filters;
|
||||
int fsvbi;
|
||||
char *fileName;
|
||||
bool active;
|
||||
bool RefreshFilters(void);
|
||||
void Action(void);
|
||||
bool AddFilter(u_char pid, u_char tid);
|
||||
bool ShutDownFilters(void);
|
||||
public:
|
||||
cSIProcessor(const char *FileName);
|
||||
~cSIProcessor();
|
||||
void SetStatus(bool On);
|
||||
bool SetUseTSTime(bool use);
|
||||
bool AddFilter(u_char pid, u_char tid);
|
||||
bool ShutDownFilters(void);
|
||||
bool SetCurrentServiceID(unsigned short servid);
|
||||
const cSchedules *Schedules(void) { return schedules; }
|
||||
};
|
||||
|
20
i18n.c
20
i18n.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: i18n.c 1.16 2001/03/31 09:58:14 kls Exp $
|
||||
* $Id: i18n.c 1.17 2001/06/02 09:39:36 kls Exp $
|
||||
*
|
||||
* Slovenian translations provided by Miha Setina <mihasetina@softhome.net>
|
||||
* Italian translations provided by Alberto Carraro <bertocar@tin.it>
|
||||
@ -452,6 +452,12 @@ const tPhrase Phrases[] = {
|
||||
"Marca la registrazione",
|
||||
"Direkte opnamen markeren",
|
||||
},
|
||||
{ "LnbSLOF",
|
||||
"LnbSLOF",
|
||||
"LnbSLOF",
|
||||
"LnbSLOF",
|
||||
"LnbSLOF",
|
||||
},
|
||||
{ "LnbFrequLo",
|
||||
"Untere LNB-Frequenz",
|
||||
"Spodnja LNB-frek.",
|
||||
@ -500,6 +506,18 @@ const tPhrase Phrases[] = {
|
||||
"", // TODO
|
||||
"", // TODO
|
||||
},
|
||||
{ "DefaultPriority",
|
||||
"Default Priorität",
|
||||
"", // TODO
|
||||
"", // TODO
|
||||
"", // TODO
|
||||
},
|
||||
{ "DefaultLifetime",
|
||||
"Default Lebensdauer",
|
||||
"", // TODO
|
||||
"", // TODO
|
||||
"", // TODO
|
||||
},
|
||||
// The days of the week:
|
||||
{ "MTWTFSS",
|
||||
"MDMDFSS",
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: interface.c 1.35 2001/02/18 10:46:13 kls Exp $
|
||||
* $Id: interface.c 1.36 2001/06/02 09:05:54 kls Exp $
|
||||
*/
|
||||
|
||||
#include "interface.h"
|
||||
@ -281,9 +281,9 @@ void cInterface::Title(const char *s)
|
||||
|
||||
void cInterface::Status(const char *s, eDvbColor FgColor, eDvbColor BgColor)
|
||||
{
|
||||
ClearEol(0, -3, s ? BgColor : clrBackground);
|
||||
ClearEol(0, -2, s ? BgColor : clrBackground);
|
||||
if (s)
|
||||
Write(0, -3, s, FgColor, BgColor);
|
||||
Write(0, -2, s, FgColor, BgColor);
|
||||
}
|
||||
|
||||
void cInterface::Info(const char *s)
|
||||
|
54
menu.c
54
menu.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: menu.c 1.70 2001/03/18 10:16:56 kls Exp $
|
||||
* $Id: menu.c 1.71 2001/06/02 09:59:54 kls Exp $
|
||||
*/
|
||||
|
||||
#include "menu.h"
|
||||
@ -539,9 +539,9 @@ cMenuEditChannel::cMenuEditChannel(int Index)
|
||||
Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hv"));
|
||||
Add(new cMenuEditIntItem( tr("Diseqc"), &data.diseqc, 0, 10)); //TODO exact limits???
|
||||
Add(new cMenuEditIntItem( tr("Srate"), &data.srate, 22000, 27500)); //TODO exact limits - toggle???
|
||||
Add(new cMenuEditIntItem( tr("Vpid"), &data.vpid, 0, 10000)); //TODO exact limits???
|
||||
Add(new cMenuEditIntItem( tr("Apid"), &data.apid, 0, 10000)); //TODO exact limits???
|
||||
Add(new cMenuEditIntItem( tr("Tpid"), &data.tpid, 0, 10000)); //TODO exact limits???
|
||||
Add(new cMenuEditIntItem( tr("Vpid"), &data.vpid, 0, 0xFFFE));
|
||||
Add(new cMenuEditIntItem( tr("Apid"), &data.apid, 0, 0xFFFE));
|
||||
Add(new cMenuEditIntItem( tr("Tpid"), &data.tpid, 0, 0xFFFE));
|
||||
Add(new cMenuEditIntItem( tr("CA"), &data.ca, 0, cDvbApi::NumDvbApis));
|
||||
Add(new cMenuEditIntItem( tr("Pnr"), &data.pnr, 0));
|
||||
}
|
||||
@ -589,7 +589,7 @@ void cMenuChannelItem::Set(void)
|
||||
if (!channel->groupSep)
|
||||
asprintf(&buffer, "%d\t%s", channel->number, channel->name );
|
||||
else
|
||||
asprintf(&buffer, "\t%s", channel->name);
|
||||
asprintf(&buffer, "\t%s", channel->name);
|
||||
SetText(buffer, false);
|
||||
}
|
||||
|
||||
@ -904,13 +904,13 @@ cMenuEditTimer::cMenuEditTimer(int Index, bool New)
|
||||
if (New)
|
||||
data.active = 1;
|
||||
Add(new cMenuEditBoolItem(tr("Active"), &data.active));
|
||||
Add(new cMenuEditChanItem(tr("Channel"), &data.channel));
|
||||
Add(new cMenuEditDayItem( tr("Day"), &data.day));
|
||||
Add(new cMenuEditTimeItem(tr("Start"), &data.start));
|
||||
Add(new cMenuEditTimeItem(tr("Stop"), &data.stop));
|
||||
Add(new cMenuEditChanItem(tr("Channel"), &data.channel));
|
||||
Add(new cMenuEditDayItem( tr("Day"), &data.day));
|
||||
Add(new cMenuEditTimeItem(tr("Start"), &data.start));
|
||||
Add(new cMenuEditTimeItem(tr("Stop"), &data.stop));
|
||||
//TODO VPS???
|
||||
Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, 99));
|
||||
Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, 99));
|
||||
Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, MAXPRIORITY));
|
||||
Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, MAXLIFETIME));
|
||||
Add(new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file), FileNameChars));
|
||||
}
|
||||
}
|
||||
@ -963,9 +963,9 @@ void cMenuTimerItem::Set(void)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
asprintf(&buffer, "%c\t%d\t%s\t%02d:%02d\t%02d:%02d\t%s",
|
||||
timer->active ? '>' : ' ',
|
||||
timer->channel,
|
||||
timer->PrintDay(timer->day),
|
||||
timer->active ? '>' : ' ',
|
||||
timer->channel,
|
||||
timer->PrintDay(timer->day),
|
||||
timer->start / 100,
|
||||
timer->start % 100,
|
||||
timer->stop / 100,
|
||||
@ -1265,7 +1265,7 @@ eOSState cMenuWhatsOn::Switch(void)
|
||||
eOSState cMenuWhatsOn::Record(void)
|
||||
{
|
||||
cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current());
|
||||
if (item) {
|
||||
if (item) {
|
||||
cTimer *timer = new cTimer(item->eventInfo);
|
||||
cTimer *t = Timers.GetTimer(timer);
|
||||
if (!t) {
|
||||
@ -1391,7 +1391,7 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel)
|
||||
eOSState cMenuSchedule::Record(void)
|
||||
{
|
||||
cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current());
|
||||
if (item) {
|
||||
if (item) {
|
||||
cTimer *timer = new cTimer(item->eventInfo);
|
||||
cTimer *t = Timers.GetTimer(timer);
|
||||
if (!t) {
|
||||
@ -1608,6 +1608,7 @@ void cMenuSetup::Set(void)
|
||||
Add(new cMenuEditBoolItem(tr("ShowInfoOnChSwitch"), &data.ShowInfoOnChSwitch));
|
||||
Add(new cMenuEditBoolItem(tr("MenuScrollPage"), &data.MenuScrollPage));
|
||||
Add(new cMenuEditBoolItem(tr("MarkInstantRecord"), &data.MarkInstantRecord));
|
||||
Add(new cMenuEditIntItem( tr("LnbSLOF"), &data.LnbSLOF));
|
||||
Add(new cMenuEditIntItem( tr("LnbFrequLo"), &data.LnbFrequLo));
|
||||
Add(new cMenuEditIntItem( tr("LnbFrequHi"), &data.LnbFrequHi));
|
||||
Add(new cMenuEditBoolItem(tr("SetSystemTime"), &data.SetSystemTime));
|
||||
@ -1615,7 +1616,9 @@ void cMenuSetup::Set(void)
|
||||
Add(new cMenuEditIntItem( tr("MarginStop"), &data.MarginStop));
|
||||
Add(new cMenuEditIntItem( tr("EPGScanTimeout"), &data.EPGScanTimeout));
|
||||
Add(new cMenuEditIntItem( tr("SVDRPTimeout"), &data.SVDRPTimeout));
|
||||
Add(new cMenuEditIntItem( tr("PrimaryLimit"), &data.PrimaryLimit));
|
||||
Add(new cMenuEditIntItem( tr("PrimaryLimit"), &data.PrimaryLimit, 0, MAXPRIORITY));
|
||||
Add(new cMenuEditIntItem( tr("DefaultPriority"), &data.DefaultPriority, 0, MAXPRIORITY));
|
||||
Add(new cMenuEditIntItem( tr("DefaultLifetime"), &data.DefaultLifetime, 0, MAXLIFETIME));
|
||||
}
|
||||
|
||||
eOSState cMenuSetup::ProcessKey(eKeys Key)
|
||||
@ -1945,11 +1948,14 @@ cRecordControl::cRecordControl(cDvbApi *DvbApi, cTimer *Timer)
|
||||
asprintf(&instantId, cDvbApi::NumDvbApis > 1 ? "%s - %d" : "%s", Channels.GetChannelNameByNumber(timer->channel), dvbApi->Index() + 1);
|
||||
}
|
||||
timer->SetRecording(true);
|
||||
Channels.SwitchTo(timer->channel, dvbApi);
|
||||
cRecording Recording(timer);
|
||||
if (dvbApi->StartRecord(Recording.FileName(), Channels.GetByNumber(timer->channel)->ca, timer->priority))
|
||||
Recording.WriteSummary();
|
||||
Interface->DisplayRecording(dvbApi->Index(), true);
|
||||
if (Channels.SwitchTo(timer->channel, dvbApi)) {
|
||||
cRecording Recording(timer);
|
||||
if (dvbApi->StartRecord(Recording.FileName(), Channels.GetByNumber(timer->channel)->ca, timer->priority))
|
||||
Recording.WriteSummary();
|
||||
Interface->DisplayRecording(dvbApi->Index(), true);
|
||||
}
|
||||
else
|
||||
cThread::EmergencyExit(true);
|
||||
}
|
||||
|
||||
cRecordControl::~cRecordControl()
|
||||
@ -1979,7 +1985,7 @@ bool cRecordControl::Process(void)
|
||||
{
|
||||
if (!timer || !timer->Matches())
|
||||
return false;
|
||||
AssertFreeDiskSpace();
|
||||
AssertFreeDiskSpace(timer->priority);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1993,7 +1999,7 @@ bool cRecordControls::Start(cTimer *Timer)
|
||||
cChannel *channel = Channels.GetByNumber(ch);
|
||||
|
||||
if (channel) {
|
||||
cDvbApi *dvbApi = cDvbApi::GetDvbApi(channel->ca, Timer ? Timer->priority : DEFAULTPRIORITY);
|
||||
cDvbApi *dvbApi = cDvbApi::GetDvbApi(channel->ca, Timer ? Timer->priority : Setup.DefaultPriority);
|
||||
if (dvbApi) {
|
||||
Stop(dvbApi);
|
||||
for (int i = 0; i < MAXDVBAPI; i++) {
|
||||
|
4
osd.h
4
osd.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: osd.h 1.20 2001/02/03 15:13:59 kls Exp $
|
||||
* $Id: osd.h 1.21 2001/06/02 09:04:19 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __OSD_H
|
||||
@ -14,7 +14,7 @@
|
||||
#include "interface.h"
|
||||
#include "tools.h"
|
||||
|
||||
#define MAXOSDITEMS 9
|
||||
#define MAXOSDITEMS (MenuLines - 4)
|
||||
|
||||
enum eOSState { osUnknown,
|
||||
osMenu,
|
||||
|
21
recording.c
21
recording.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: recording.c 1.29 2001/03/31 09:38:30 kls Exp $
|
||||
* $Id: recording.c 1.30 2001/06/02 10:07:01 kls Exp $
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
@ -39,7 +39,7 @@
|
||||
#define DELETEDLIFETIME 1 // hours after which a deleted recording will be actually removed
|
||||
#define REMOVECHECKDELTA 3600 // seconds between checks for removing deleted files
|
||||
#define DISKCHECKDELTA 300 // seconds between checks for free disk space
|
||||
#define REMOVELATENCY 10 // seconds to wait until next check after removing a file
|
||||
#define REMOVELATENCY 10 // seconds to wait until next check after removing a file
|
||||
|
||||
void RemoveDeletedRecordings(void)
|
||||
{
|
||||
@ -66,7 +66,7 @@ void RemoveDeletedRecordings(void)
|
||||
}
|
||||
}
|
||||
|
||||
void AssertFreeDiskSpace(void)
|
||||
void AssertFreeDiskSpace(int Priority)
|
||||
{
|
||||
// With every call to this function we try to actually remove
|
||||
// a file, or mark a file for removal ("delete" it), so that
|
||||
@ -94,10 +94,13 @@ void AssertFreeDiskSpace(void)
|
||||
cRecording *r = Recordings.First();
|
||||
cRecording *r0 = NULL;
|
||||
while (r) {
|
||||
if ((time(NULL) - r->start) / SECSINDAY > r->lifetime) {
|
||||
if (r->lifetime == MAXLIFETIME)
|
||||
continue; // recordings with MAXLIFETIME live forever
|
||||
if ((r->lifetime == 0 && Priority > r->priority) || // the recording has guaranteed lifetime and the new recording has higher priority
|
||||
(time(NULL) - r->start) / SECSINDAY > r->lifetime) { // the recording's guaranteed lifetime has expired
|
||||
if (r0) {
|
||||
if (r->priority < r0->priority)
|
||||
r0 = r;
|
||||
if (r->priority < r0->priority || (r->priority == r0->priority && r->start < r0->start))
|
||||
r0 = r; // in any case we delete the one with the lowest priority (or the older one in case of equal priorities)
|
||||
}
|
||||
else
|
||||
r0 = r;
|
||||
@ -153,7 +156,7 @@ int cResumeFile::Read(void)
|
||||
bool cResumeFile::Save(int Index)
|
||||
{
|
||||
if (fileName) {
|
||||
int f = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
int f = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
if (f >= 0) {
|
||||
if (write(f, &Index, sizeof(Index)) != sizeof(Index))
|
||||
LOG_ERROR_STR(fileName);
|
||||
@ -183,7 +186,7 @@ cRecording::cRecording(cTimer *Timer)
|
||||
for (char *p = name; *p; p++) {
|
||||
switch (*p) {
|
||||
case '\n': *p = ' '; break;
|
||||
case '/': *p = '-'; break;
|
||||
case '/': *p = '-'; break;
|
||||
}
|
||||
}
|
||||
summary = Timer->summary ? strdup(Timer->summary) : NULL;
|
||||
@ -239,7 +242,7 @@ cRecording::cRecording(const char *FileName)
|
||||
delete summary;
|
||||
summary = NULL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
esyslog(LOG_ERR, "can't allocate %d byte of memory for summary file '%s'", size + 1, SummaryFileName);
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: recording.h 1.13 2001/02/11 10:45:52 kls Exp $
|
||||
* $Id: recording.h 1.14 2001/06/02 10:00:25 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __RECORDING_H
|
||||
@ -15,7 +15,7 @@
|
||||
#include "tools.h"
|
||||
|
||||
void RemoveDeletedRecordings(void);
|
||||
void AssertFreeDiskSpace(void);
|
||||
void AssertFreeDiskSpace(int Priority);
|
||||
|
||||
class cResumeFile {
|
||||
private:
|
||||
|
499
remux.c
499
remux.c
@ -4,7 +4,11 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: remux.c 1.1 2001/03/31 08:42:17 kls Exp $
|
||||
* The parts of this code that implement cTS2PES have been taken from
|
||||
* the Linux DVB driver's 'tuxplayer' example and were rewritten to suit
|
||||
* VDR's needs.
|
||||
*
|
||||
* $Id: remux.c 1.2 2001/05/27 10:27:15 kls Exp $
|
||||
*/
|
||||
|
||||
/* The calling interface of the 'cRemux::Process()' function is defined
|
||||
@ -62,17 +66,364 @@
|
||||
*/
|
||||
|
||||
#include "remux.h"
|
||||
#include "thread.h"
|
||||
#include "tools.h"
|
||||
|
||||
#if defined(REMUX_NONE)
|
||||
// --- cTS2PES ---------------------------------------------------------------
|
||||
|
||||
cRemux::cRemux(void)
|
||||
#include <netinet/in.h>
|
||||
|
||||
//XXX TODO: these should really be available in some driver header file!
|
||||
#define PROG_STREAM_MAP 0xBC
|
||||
#ifndef PRIVATE_STREAM1
|
||||
#define PRIVATE_STREAM1 0xBD
|
||||
#endif
|
||||
#define PADDING_STREAM 0xBE
|
||||
#ifndef PRIVATE_STREAM2
|
||||
#define PRIVATE_STREAM2 0xBF
|
||||
#endif
|
||||
#define AUDIO_STREAM_S 0xC0
|
||||
#define AUDIO_STREAM_E 0xDF
|
||||
#define VIDEO_STREAM_S 0xE0
|
||||
#define VIDEO_STREAM_E 0xEF
|
||||
#define ECM_STREAM 0xF0
|
||||
#define EMM_STREAM 0xF1
|
||||
#define DSM_CC_STREAM 0xF2
|
||||
#define ISO13522_STREAM 0xF3
|
||||
#define PROG_STREAM_DIR 0xFF
|
||||
|
||||
//pts_dts flags
|
||||
#define PTS_ONLY 0x80
|
||||
|
||||
#define TS_SIZE 188
|
||||
#define PAY_START 0x40
|
||||
#define PID_MASK_HI 0x1F
|
||||
//flags
|
||||
#define ADAPT_FIELD 0x20
|
||||
//XXX TODO
|
||||
|
||||
#define MAX_PLENGTH 0xFFFF
|
||||
#define MMAX_PLENGTH (4*MAX_PLENGTH)
|
||||
|
||||
#define IPACKS 2048
|
||||
|
||||
class cTS2PES {
|
||||
private:
|
||||
int size;
|
||||
int found;
|
||||
int count;
|
||||
uint8_t *buf;
|
||||
uint8_t cid;
|
||||
int plength;
|
||||
uint8_t plen[2];
|
||||
uint8_t flag1;
|
||||
uint8_t flag2;
|
||||
uint8_t hlength;
|
||||
int mpeg;
|
||||
uint8_t check;
|
||||
int which;
|
||||
bool done;
|
||||
uint8_t *resultBuffer;
|
||||
int *resultCount;
|
||||
static uint8_t headr[];
|
||||
void store(uint8_t *Data, int Count);
|
||||
void reset_ipack(void);
|
||||
void send_ipack(void);
|
||||
void write_ipack(const uint8_t *Data, int Count);
|
||||
void instant_repack(const uint8_t *Buf, int Count);
|
||||
public:
|
||||
cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size);
|
||||
~cTS2PES();
|
||||
void ts_to_pes(const uint8_t *Buf); // don't need count (=188)
|
||||
};
|
||||
|
||||
uint8_t cTS2PES::headr[] = { 0x00, 0x00, 0x01 };
|
||||
|
||||
cTS2PES::cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size)
|
||||
{
|
||||
resultBuffer = ResultBuffer;
|
||||
resultCount = ResultCount;
|
||||
size = Size;
|
||||
|
||||
if (!(buf = new uint8_t[size]))
|
||||
esyslog(LOG_ERR, "Not enough memory for ts_transform");
|
||||
|
||||
reset_ipack();
|
||||
}
|
||||
|
||||
cTS2PES::~cTS2PES()
|
||||
{
|
||||
delete buf;
|
||||
}
|
||||
|
||||
void cTS2PES::store(uint8_t *Data, int Count)
|
||||
{
|
||||
//XXX overflow check???
|
||||
memcpy(resultBuffer + *resultCount, Data, Count);
|
||||
*resultCount += Count;
|
||||
}
|
||||
|
||||
void cTS2PES::reset_ipack(void)
|
||||
{
|
||||
found = 0;
|
||||
cid = 0;
|
||||
plength = 0;
|
||||
flag1 = 0;
|
||||
flag2 = 0;
|
||||
hlength = 0;
|
||||
mpeg = 0;
|
||||
check = 0;
|
||||
which = 0;
|
||||
done = false;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void cTS2PES::send_ipack(void)
|
||||
{
|
||||
if (count < 10)
|
||||
return;
|
||||
buf[3] = cid;
|
||||
buf[4] = (uint8_t)(((count - 6) & 0xFF00) >> 8);
|
||||
buf[5] = (uint8_t)((count - 6) & 0x00FF);
|
||||
store(buf, count);
|
||||
|
||||
switch (mpeg) {
|
||||
case 2:
|
||||
buf[6] = 0x80;
|
||||
buf[7] = 0x00;
|
||||
buf[8] = 0x00;
|
||||
count = 9;
|
||||
break;
|
||||
case 1:
|
||||
buf[6] = 0x0F;
|
||||
count = 7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cTS2PES::write_ipack(const uint8_t *Data, int Count)
|
||||
{
|
||||
if (count < 6) {
|
||||
memcpy(buf, headr, 3);
|
||||
count = 6;
|
||||
}
|
||||
|
||||
if (count + Count < size) {
|
||||
memcpy(buf + count, Data, Count);
|
||||
count += Count;
|
||||
}
|
||||
else {
|
||||
int rest = size - count;
|
||||
memcpy(buf + count, Data, rest);
|
||||
count += rest;
|
||||
send_ipack();
|
||||
if (Count - rest > 0)
|
||||
write_ipack(Data + rest, Count - rest);
|
||||
}
|
||||
}
|
||||
|
||||
void cTS2PES::instant_repack(const uint8_t *Buf, int Count)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (c < Count && (mpeg == 0 || (mpeg == 1 && found < 7) || (mpeg == 2 && found < 9)) && (found < 5 || !done)) {
|
||||
switch (found ) {
|
||||
case 0:
|
||||
case 1:
|
||||
if (Buf[c] == 0x00)
|
||||
found++;
|
||||
else
|
||||
found = 0;
|
||||
c++;
|
||||
break;
|
||||
case 2:
|
||||
if (Buf[c] == 0x01)
|
||||
found++;
|
||||
else if (Buf[c] != 0)
|
||||
found = 0;
|
||||
c++;
|
||||
break;
|
||||
case 3:
|
||||
cid = 0;
|
||||
switch (Buf[c]) {
|
||||
case PROG_STREAM_MAP:
|
||||
case PRIVATE_STREAM2:
|
||||
case PROG_STREAM_DIR:
|
||||
case ECM_STREAM :
|
||||
case EMM_STREAM :
|
||||
case PADDING_STREAM :
|
||||
case DSM_CC_STREAM :
|
||||
case ISO13522_STREAM:
|
||||
done = true;
|
||||
case PRIVATE_STREAM1:
|
||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
||||
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
||||
found++;
|
||||
cid = Buf[c++];
|
||||
break;
|
||||
default:
|
||||
found = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (Count - c > 1) {
|
||||
unsigned short *pl = (unsigned short *)(Buf + c);
|
||||
plength = ntohs(*pl);
|
||||
c += 2;
|
||||
found += 2;
|
||||
}
|
||||
else {
|
||||
plen[0] = Buf[c];
|
||||
found++;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 5: {
|
||||
plen[1] = Buf[c++];
|
||||
unsigned short *pl = (unsigned short *)plen;
|
||||
plength = ntohs(*pl);
|
||||
found++;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (!done) {
|
||||
flag1 = Buf[c++];
|
||||
found++;
|
||||
if ((flag1 & 0xC0) == 0x80 )
|
||||
mpeg = 2;
|
||||
else {
|
||||
esyslog(LOG_INFO, "ERROR: can't record MPEG1!");
|
||||
hlength = 0;
|
||||
which = 0;
|
||||
mpeg = 1;
|
||||
flag2 = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (!done && mpeg == 2) {
|
||||
flag2 = Buf[c++];
|
||||
found++;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (!done && mpeg == 2) {
|
||||
hlength = Buf[c++];
|
||||
found++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!plength)
|
||||
plength = MMAX_PLENGTH - 6;
|
||||
|
||||
if (done || ((mpeg == 2 && found >= 9) || (mpeg == 1 && found >= 7))) {
|
||||
switch (cid) {
|
||||
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
||||
case PRIVATE_STREAM1:
|
||||
|
||||
if (mpeg == 2 && found == 9) {
|
||||
write_ipack(&flag1, 1);
|
||||
write_ipack(&flag2, 1);
|
||||
write_ipack(&hlength, 1);
|
||||
}
|
||||
|
||||
if (mpeg == 2 && (flag2 & PTS_ONLY) && found < 14) {
|
||||
while (c < Count && found < 14) {
|
||||
write_ipack(Buf + c, 1);
|
||||
c++;
|
||||
found++;
|
||||
}
|
||||
if (c == Count)
|
||||
return;
|
||||
}
|
||||
|
||||
while (c < Count && found < plength + 6) {
|
||||
int l = Count - c;
|
||||
if (l + found > plength + 6)
|
||||
l = plength + 6 - found;
|
||||
write_ipack(Buf + c, l);
|
||||
found += l;
|
||||
c += l;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (done) {
|
||||
if (found + Count - c < plength + 6) {
|
||||
found += Count - c;
|
||||
c = Count;
|
||||
}
|
||||
else {
|
||||
c += plength + 6 - found;
|
||||
found = plength + 6;
|
||||
}
|
||||
}
|
||||
|
||||
if (plength && found == plength + 6) {
|
||||
send_ipack();
|
||||
reset_ipack();
|
||||
if (c < Count)
|
||||
instant_repack(Buf + c, Count - c);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cTS2PES::ts_to_pes(const uint8_t *Buf) // don't need count (=188)
|
||||
{
|
||||
if (!Buf)
|
||||
return;
|
||||
|
||||
if (Buf[1] & PAY_START) {
|
||||
if (plength == MMAX_PLENGTH - 6 && found > 6) {
|
||||
plength = found - 6;
|
||||
found = 0;
|
||||
send_ipack();
|
||||
reset_ipack();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t off = 0;
|
||||
|
||||
if (Buf[3] & ADAPT_FIELD) { // adaptation field?
|
||||
off = Buf[4] + 1;
|
||||
if (off + 4 > 187)
|
||||
return;
|
||||
}
|
||||
|
||||
instant_repack(Buf + 4 + off, TS_SIZE - 4 - off);
|
||||
}
|
||||
|
||||
// --- cRemux ----------------------------------------------------------------
|
||||
|
||||
cRemux::cRemux(dvb_pid_t VPid, dvb_pid_t APid, bool ExitOnFailure)
|
||||
{
|
||||
vPid = VPid;
|
||||
aPid = APid;
|
||||
exitOnFailure = ExitOnFailure;
|
||||
synced = false;
|
||||
skipped = 0;
|
||||
resultCount = resultDelivered = 0;
|
||||
vTS2PES = new cTS2PES(resultBuffer, &resultCount, IPACKS);
|
||||
aTS2PES = new cTS2PES(resultBuffer, &resultCount, IPACKS);
|
||||
}
|
||||
|
||||
cRemux::~cRemux()
|
||||
{
|
||||
delete vTS2PES;
|
||||
delete aTS2PES;
|
||||
}
|
||||
|
||||
int cRemux::GetPid(const uchar *Data)
|
||||
{
|
||||
return (((uint16_t)Data[0] & PID_MASK_HI) << 8) | (Data[1] & 0xFF);
|
||||
}
|
||||
|
||||
int cRemux::GetPacketLength(const uchar *Data, int Count, int Offset)
|
||||
@ -104,70 +455,130 @@ int cRemux::ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &Pic
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uchar *cRemux::Process(const uchar *Data, int &Count, int &Result, uchar &PictureType)
|
||||
const uchar *cRemux::Process(const uchar *Data, int &Count, int &Result, uchar *PictureType)
|
||||
{
|
||||
int Skip = 0;
|
||||
uchar dummyPictureType;
|
||||
if (!PictureType)
|
||||
PictureType = &dummyPictureType;
|
||||
|
||||
PictureType = NO_PICTURE;
|
||||
/*XXX
|
||||
// test recording the raw TS:
|
||||
Result = Count;
|
||||
*PictureType = I_FRAME;
|
||||
return Data;
|
||||
XXX*/
|
||||
|
||||
if (Count >= MINVIDEODATA) {
|
||||
for (int i = 0; i < Count; i++) {
|
||||
if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1) {
|
||||
switch (Data[i + 3]) {
|
||||
// Remove any previously delivered data from the result buffer:
|
||||
|
||||
if (resultDelivered) {
|
||||
if (resultDelivered < resultCount)
|
||||
memmove(resultBuffer, resultBuffer + resultDelivered, resultCount - resultDelivered);
|
||||
resultCount -= resultDelivered;
|
||||
resultDelivered = 0;
|
||||
}
|
||||
|
||||
// Convert incoming TS data into multiplexed PES:
|
||||
|
||||
int used = 0;
|
||||
for (int i = 0; i < Count; i += TS_SIZE) {
|
||||
if (Count - i < TS_SIZE)
|
||||
break;
|
||||
dvb_pid_t pid = GetPid(Data + i + 1);
|
||||
if (Data[i + 3] & 0x10) { // got payload
|
||||
if (pid == vPid)
|
||||
vTS2PES->ts_to_pes(Data + i);
|
||||
else if (pid == aPid)
|
||||
aTS2PES->ts_to_pes(Data + i);
|
||||
}
|
||||
used += TS_SIZE;
|
||||
if (resultCount > (int)sizeof(resultBuffer) / 2)
|
||||
break;
|
||||
}
|
||||
Count = used;
|
||||
|
||||
/*XXX
|
||||
// test recording without determining the real frame borders:
|
||||
*PictureType = I_FRAME;
|
||||
Result = resultDelivered = resultCount;
|
||||
return Result ? resultBuffer : NULL;
|
||||
XXX*/
|
||||
|
||||
// Check if we're getting anywhere here:
|
||||
|
||||
if (!synced && skipped >= 0) {
|
||||
if (skipped > 1024*1024) {
|
||||
esyslog(LOG_ERR, "ERROR: no useful data seen within %d byte of video stream", skipped);
|
||||
skipped = -1;
|
||||
if (exitOnFailure)
|
||||
cThread::EmergencyExit(true);
|
||||
}
|
||||
else
|
||||
skipped += Count;
|
||||
}
|
||||
|
||||
// Check for frame borders:
|
||||
|
||||
*PictureType = NO_PICTURE;
|
||||
|
||||
if (resultCount >= MINVIDEODATA) {
|
||||
for (int i = 0; i < resultCount; i++) {
|
||||
if (resultBuffer[i] == 0 && resultBuffer[i + 1] == 0 && resultBuffer[i + 2] == 1) {
|
||||
switch (resultBuffer[i + 3]) {
|
||||
case SC_VIDEO:
|
||||
{
|
||||
uchar pt = NO_PICTURE;
|
||||
int l = ScanVideoPacket(Data, Count, i, pt);
|
||||
if (l < 0) {
|
||||
if (Skip < Count)
|
||||
Count = Skip;
|
||||
int l = ScanVideoPacket(resultBuffer, resultCount, i, pt);
|
||||
if (l < 0)
|
||||
return NULL; // no useful data found, wait for more
|
||||
}
|
||||
if (pt != NO_PICTURE) {
|
||||
if (pt < I_FRAME || B_FRAME < pt) {
|
||||
esyslog(LOG_ERR, "ERROR: unknown picture type '%d'", pt);
|
||||
}
|
||||
else if (PictureType == NO_PICTURE) {
|
||||
if (!synced) {
|
||||
if (pt == I_FRAME) {
|
||||
Skip = i;
|
||||
synced = true;
|
||||
}
|
||||
else {
|
||||
i += l;
|
||||
Skip = i;
|
||||
break;
|
||||
}
|
||||
else if (!synced) {
|
||||
if (pt == I_FRAME) {
|
||||
resultDelivered = i; // will drop everything before this position
|
||||
synced = true;
|
||||
}
|
||||
else {
|
||||
resultDelivered = i + l; // will drop everything before and including this packet
|
||||
return NULL;
|
||||
}
|
||||
if (synced)
|
||||
PictureType = pt;
|
||||
}
|
||||
else {
|
||||
Count = i;
|
||||
Result = i - Skip;
|
||||
return Data + Skip;
|
||||
}
|
||||
}
|
||||
else if (!synced) {
|
||||
i += l;
|
||||
Skip = i;
|
||||
break;
|
||||
if (synced) {
|
||||
*PictureType = pt;
|
||||
Result = l;
|
||||
const uchar *p = resultBuffer + resultDelivered;
|
||||
resultDelivered += l;
|
||||
return p;
|
||||
}
|
||||
else {
|
||||
resultDelivered = i + l; // will drop everything before and including this packet
|
||||
return NULL;
|
||||
}
|
||||
i += l - 1; // -1 to compensate for i++ in the loop!
|
||||
}
|
||||
break;
|
||||
case SC_AUDIO:
|
||||
i += GetPacketLength(Data, Count, i) - 1; // -1 to compensate for i++ in the loop!
|
||||
{
|
||||
int l = GetPacketLength(resultBuffer, resultCount, i);
|
||||
if (l < 0)
|
||||
return NULL; // no useful data found, wait for more
|
||||
if (synced) {
|
||||
Result = l;
|
||||
const uchar *p = resultBuffer + resultDelivered;
|
||||
resultDelivered += l;
|
||||
return p;
|
||||
}
|
||||
else {
|
||||
resultDelivered = i + l; // will drop everything before and including this packet
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Skip < Count)
|
||||
Count = Skip;
|
||||
return NULL; // no useful data found, wait for more
|
||||
}
|
||||
|
||||
#elif defined(REMUX_TEST)
|
||||
#endif
|
||||
|
||||
|
27
remux.h
27
remux.h
@ -4,16 +4,14 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: remux.h 1.1 2001/03/31 08:42:27 kls Exp $
|
||||
* $Id: remux.h 1.2 2001/05/26 11:50:52 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __REMUX_H
|
||||
#define __REMUX_H
|
||||
|
||||
// There are various experiments with different types of remultiplexers
|
||||
// going on at the moment. Select the remultiplexer here:
|
||||
#define REMUX_NONE 1
|
||||
//#define REMUX_TEST 1
|
||||
#include <time.h> //XXX FIXME: DVB/ost/include/ost/dmx.h should include <time.h> itself!!!
|
||||
#include <ost/dmx.h>
|
||||
|
||||
// Picture types:
|
||||
#define NO_PICTURE 0
|
||||
@ -21,6 +19,7 @@
|
||||
#define P_FRAME 2
|
||||
#define B_FRAME 3
|
||||
|
||||
//XXX -> remux.c???
|
||||
// Start codes:
|
||||
#define SC_PICTURE 0x00 // "picture header"
|
||||
#define SC_SEQU 0xB3 // "sequence header"
|
||||
@ -30,22 +29,28 @@
|
||||
#define SC_VIDEO 0xE0
|
||||
|
||||
// The minimum amount of video data necessary to identify frames:
|
||||
#define MINVIDEODATA (256*1024) // just a safe guess (max. size of any frame block, plus some safety)
|
||||
#define MINVIDEODATA (16*1024) // just a safe guess (max. size of any frame block, plus some safety)
|
||||
|
||||
typedef unsigned char uchar;
|
||||
class cTS2PES;
|
||||
|
||||
class cRemux {
|
||||
private:
|
||||
#if defined(REMUX_NONE)
|
||||
bool exitOnFailure;
|
||||
bool synced;
|
||||
int skipped;
|
||||
dvb_pid_t vPid, aPid;
|
||||
cTS2PES *vTS2PES, *aTS2PES;
|
||||
uchar resultBuffer[MINVIDEODATA * 4];//XXX
|
||||
int resultCount;
|
||||
int resultDelivered;
|
||||
int GetPid(const uchar *Data);
|
||||
int GetPacketLength(const uchar *Data, int Count, int Offset);
|
||||
int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType);
|
||||
#elif defined(REMUX_TEST)
|
||||
#endif
|
||||
public:
|
||||
cRemux(void);
|
||||
cRemux(dvb_pid_t VPid, dvb_pid_t APid, bool ExitOnFailure = false);
|
||||
~cRemux();
|
||||
const uchar *Process(const uchar *Data, int &Count, int &Result, uchar &PictureType);
|
||||
const uchar *Process(const uchar *Data, int &Count, int &Result, uchar *PictureType = NULL);
|
||||
};
|
||||
|
||||
#endif // __REMUX_H
|
||||
|
37
ringbuffer.c
37
ringbuffer.c
@ -7,7 +7,7 @@
|
||||
* Parts of this file were inspired by the 'ringbuffy.c' from the
|
||||
* LinuxDVB driver (see linuxtv.org).
|
||||
*
|
||||
* $Id: ringbuffer.c 1.1 2001/03/18 16:47:00 kls Exp $
|
||||
* $Id: ringbuffer.c 1.2 2001/05/20 11:58:08 kls Exp $
|
||||
*/
|
||||
|
||||
#include "ringbuffer.h"
|
||||
@ -37,9 +37,10 @@ public:
|
||||
|
||||
// --- cRingBuffer ------------------------------------------------------------
|
||||
|
||||
cRingBuffer::cRingBuffer(int Size)
|
||||
cRingBuffer::cRingBuffer(int Size, bool Statistics)
|
||||
{
|
||||
size = Size;
|
||||
statistics = Statistics;
|
||||
buffer = NULL;
|
||||
inputThread = NULL;
|
||||
outputThread = NULL;
|
||||
@ -60,7 +61,17 @@ cRingBuffer::~cRingBuffer()
|
||||
delete inputThread;
|
||||
delete outputThread;
|
||||
delete buffer;
|
||||
dsyslog(LOG_INFO, "buffer stats: %d (%d%%) used", maxFill, maxFill * 100 / (size - 1));
|
||||
if (statistics)
|
||||
dsyslog(LOG_INFO, "buffer stats: %d (%d%%) used", maxFill, maxFill * 100 / (size - 1));
|
||||
}
|
||||
|
||||
int cRingBuffer::Available(void)
|
||||
{
|
||||
mutex.Lock();
|
||||
int diff = head - tail;
|
||||
int cont = (diff >= 0) ? diff : size + diff;
|
||||
mutex.Unlock();
|
||||
return cont;
|
||||
}
|
||||
|
||||
void cRingBuffer::Clear(void)
|
||||
@ -78,17 +89,17 @@ int cRingBuffer::Put(const uchar *Data, int Count)
|
||||
int diff = tail - head;
|
||||
mutex.Unlock();
|
||||
int free = (diff > 0) ? diff - 1 : size + diff - 1;
|
||||
// Statistics:
|
||||
int fill = size - free - 1 + Count;
|
||||
if (fill >= size)
|
||||
fill = size - 1;
|
||||
if (fill > maxFill) {
|
||||
maxFill = fill;
|
||||
int percent = maxFill * 100 / (size - 1);
|
||||
if (percent > 75)
|
||||
dsyslog(LOG_INFO, "buffer usage: %d%%", percent);
|
||||
if (statistics) {
|
||||
int fill = size - free - 1 + Count;
|
||||
if (fill >= size)
|
||||
fill = size - 1;
|
||||
if (fill > maxFill) {
|
||||
maxFill = fill;
|
||||
int percent = maxFill * 100 / (size - 1);
|
||||
if (percent > 75)
|
||||
dsyslog(LOG_INFO, "buffer usage: %d%%", percent);
|
||||
}
|
||||
}
|
||||
//
|
||||
if (free <= 0)
|
||||
return 0;
|
||||
if (free < Count)
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: ringbuffer.h 1.1 2001/03/18 16:47:00 kls Exp $
|
||||
* $Id: ringbuffer.h 1.2 2001/05/20 11:56:44 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __RINGBUFFER_H
|
||||
@ -28,7 +28,11 @@ private:
|
||||
uchar *buffer;
|
||||
int maxFill;
|
||||
bool busy;
|
||||
bool statistics;
|
||||
protected:
|
||||
void Lock(void) { mutex.Lock(); }
|
||||
void Unlock(void) { mutex.Unlock(); }
|
||||
int Available(void);
|
||||
bool Busy(void) { return busy; }
|
||||
void Clear(void);
|
||||
// Immediately clears the ring buffer.
|
||||
@ -45,7 +49,7 @@ protected:
|
||||
// Runs as a separate thread and shall continuously call Get() to
|
||||
// retrieve data from the ring buffer and write it to a destination.
|
||||
public:
|
||||
cRingBuffer(int Size);
|
||||
cRingBuffer(int Size, bool Statistics = false);
|
||||
virtual ~cRingBuffer();
|
||||
bool Start(void);
|
||||
bool Active(void);
|
||||
|
32
runvdr
32
runvdr
@ -1,18 +1,40 @@
|
||||
#!/bin/sh
|
||||
|
||||
# runvdr: Loads the DVB driver and runs VDR
|
||||
#
|
||||
# If VDR exits abnormally, the driver will be reloaded
|
||||
# and VDR restarted.
|
||||
#
|
||||
# Set the environment variable VDRUSR to the user id you
|
||||
# want VDR to run with. If VDRUSR is not set, VDR will run
|
||||
# as 'root', which is not necessarily advisable.
|
||||
#
|
||||
# Since this script loads the DVB driver, it must be started
|
||||
# as user 'root'.
|
||||
#
|
||||
# Any command line parameters will be passed on to the
|
||||
# actual 'vdr' program.
|
||||
#
|
||||
# See the main source file 'vdr.c' for copyright information and
|
||||
# how to reach the author.
|
||||
#
|
||||
# $Id: runvdr 1.5 2001/06/01 16:23:29 kls Exp $
|
||||
|
||||
DVBDIR="../DVB/driver"
|
||||
VDRPRG="./vdr"
|
||||
VDRCMD="$VDRPRG -w 60"
|
||||
VDRCMD="$VDRPRG -w 60 $*"
|
||||
|
||||
KILLPROC="/sbin/killproc -TERM"
|
||||
|
||||
(cd $DVBDIR; make insmod)
|
||||
|
||||
while (true) do
|
||||
# (cd $DVBDIR; make reload)
|
||||
# sleep 3
|
||||
$VDRCMD
|
||||
if test $? -ne 1; then exit; fi
|
||||
su -c "$VDRCMD" $VDRUSR
|
||||
if test $? -eq 0; then exit; fi
|
||||
date
|
||||
echo "restarting VDR"
|
||||
$KILLPROC $VDRPRG
|
||||
sleep 10
|
||||
(cd $DVBDIR; make reload)
|
||||
date
|
||||
done
|
||||
|
39
thread.c
39
thread.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: thread.c 1.7 2000/12/24 12:27:21 kls Exp $
|
||||
* $Id: thread.c 1.8 2001/05/25 09:37:00 kls Exp $
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
@ -14,12 +14,41 @@
|
||||
#include <unistd.h>
|
||||
#include "tools.h"
|
||||
|
||||
// --- cMutex ----------------------------------------------------------------
|
||||
|
||||
cMutex::cMutex(void)
|
||||
{
|
||||
lockingPid = 0;
|
||||
locked = 0;
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
}
|
||||
|
||||
cMutex::~cMutex()
|
||||
{
|
||||
pthread_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
void cMutex::Lock(void)
|
||||
{
|
||||
if (getpid() != lockingPid || !locked)
|
||||
pthread_mutex_lock(&mutex);
|
||||
lockingPid = getpid();
|
||||
locked++;
|
||||
}
|
||||
|
||||
void cMutex::Unlock(void)
|
||||
{
|
||||
if (!--locked)
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
// --- cThread ---------------------------------------------------------------
|
||||
|
||||
// The signal handler is necessary to be able to use SIGIO to wake up any
|
||||
// pending 'select()' call.
|
||||
|
||||
bool cThread::signalHandlerInstalled = false;
|
||||
bool cThread::emergencyExitRequested = false;
|
||||
|
||||
cThread::cThread(void)
|
||||
{
|
||||
@ -110,6 +139,14 @@ void cThread::WakeUp(void)
|
||||
kill(parentPid, SIGIO); // makes any waiting 'select()' call return immediately
|
||||
}
|
||||
|
||||
bool cThread::EmergencyExit(bool Request)
|
||||
{
|
||||
if (!Request)
|
||||
return emergencyExitRequested;
|
||||
esyslog(LOG_ERR, "initiating emergency exit");
|
||||
return emergencyExitRequested = true; // yes, it's an assignment, not a comparison!
|
||||
}
|
||||
|
||||
// --- cThreadLock -----------------------------------------------------------
|
||||
|
||||
cThreadLock::cThreadLock(cThread *Thread)
|
||||
|
14
thread.h
14
thread.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: thread.h 1.4 2000/12/03 11:18:37 kls Exp $
|
||||
* $Id: thread.h 1.5 2001/05/25 09:36:27 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __THREAD_H
|
||||
@ -16,11 +16,13 @@
|
||||
class cMutex {
|
||||
private:
|
||||
pthread_mutex_t mutex;
|
||||
pid_t lockingPid;
|
||||
int locked;
|
||||
public:
|
||||
cMutex(void) { pthread_mutex_init(&mutex, NULL); }
|
||||
~cMutex() { pthread_mutex_destroy(&mutex); }
|
||||
void Lock(void) { pthread_mutex_lock(&mutex); }
|
||||
void Unlock(void) { pthread_mutex_unlock(&mutex); }
|
||||
cMutex(void);
|
||||
~cMutex();
|
||||
void Lock(void);
|
||||
void Unlock(void);
|
||||
};
|
||||
|
||||
class cThread {
|
||||
@ -31,6 +33,7 @@ private:
|
||||
pid_t parentPid, threadPid, lockingPid;
|
||||
int locked;
|
||||
bool running;
|
||||
static bool emergencyExitRequested;
|
||||
static bool signalHandlerInstalled;
|
||||
static void SignalHandler(int signum);
|
||||
static void *StartThread(cThread *Thread);
|
||||
@ -45,6 +48,7 @@ public:
|
||||
virtual ~cThread();
|
||||
bool Start(void);
|
||||
bool Active(void);
|
||||
static bool EmergencyExit(bool Request = false);
|
||||
};
|
||||
|
||||
// cThreadLock can be used to easily set a lock in a thread and make absolutely
|
||||
|
18
tools.c
18
tools.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: tools.c 1.33 2001/04/22 10:31:29 kls Exp $
|
||||
* $Id: tools.c 1.34 2001/05/20 08:30:54 kls Exp $
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
@ -411,6 +411,22 @@ bool cFile::FileReady(int FileDes, int TimeoutMs)
|
||||
return select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0 && FD_ISSET(FileDes, &set);
|
||||
}
|
||||
|
||||
bool cFile::FileReadyForWriting(int FileDes, int TimeoutMs)
|
||||
{
|
||||
#ifdef DEBUG_OSD
|
||||
refresh();
|
||||
#endif
|
||||
fd_set set;
|
||||
struct timeval timeout;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(FileDes, &set);
|
||||
if (TimeoutMs < 100)
|
||||
TimeoutMs = 100;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = TimeoutMs * 1000;
|
||||
return select(FD_SETSIZE, NULL, &set, NULL, &timeout) > 0 && FD_ISSET(FileDes, &set);
|
||||
}
|
||||
|
||||
// --- cSafeFile -------------------------------------------------------------
|
||||
|
||||
cSafeFile::cSafeFile(const char *FileName)
|
||||
|
3
tools.h
3
tools.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: tools.h 1.25 2001/04/01 14:13:42 kls Exp $
|
||||
* $Id: tools.h 1.26 2001/05/20 08:29:45 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TOOLS_H
|
||||
@ -67,6 +67,7 @@ public:
|
||||
bool Ready(bool Wait = true);
|
||||
static bool AnyFileReady(int FileDes = -1, int TimeoutMs = 1000);
|
||||
static bool FileReady(int FileDes, int TimeoutMs = 1000);
|
||||
static bool FileReadyForWriting(int FileDes, int TimeoutMs = 1000);
|
||||
};
|
||||
|
||||
class cSafeFile {
|
||||
|
14
vdr.c
14
vdr.c
@ -22,7 +22,7 @@
|
||||
*
|
||||
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
||||
*
|
||||
* $Id: vdr.c 1.56 2001/04/01 11:16:54 kls Exp $
|
||||
* $Id: vdr.c 1.57 2001/05/25 09:31:09 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
@ -267,6 +267,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
while (!Interrupted) {
|
||||
// Handle emergency exits:
|
||||
if (cThread::EmergencyExit()) {
|
||||
esyslog(LOG_ERR, "emergency exit requested - shutting down");
|
||||
break;
|
||||
}
|
||||
// Restart the Watchdog timer:
|
||||
if (WatchdogTimeout > 0) {
|
||||
int LatencyTime = WatchdogTimeout - alarm(WatchdogTimeout);
|
||||
@ -388,7 +393,8 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
LastActivity = time(NULL);
|
||||
}
|
||||
isyslog(LOG_INFO, "caught signal %d", Interrupted);
|
||||
if (Interrupted)
|
||||
isyslog(LOG_INFO, "caught signal %d", Interrupted);
|
||||
Setup.CurrentChannel = cDvbApi::CurrentChannel();
|
||||
Setup.Save();
|
||||
cVideoCutter::Stop();
|
||||
@ -401,5 +407,9 @@ int main(int argc, char *argv[])
|
||||
isyslog(LOG_INFO, "exiting");
|
||||
if (SysLogLevel > 0)
|
||||
closelog();
|
||||
if (cThread::EmergencyExit()) {
|
||||
esyslog(LOG_ERR, "emergency exit!");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: videodir.c 1.4 2001/02/11 13:48:30 kls Exp $
|
||||
* $Id: videodir.c 1.5 2001/05/01 09:48:57 kls Exp $
|
||||
*/
|
||||
|
||||
#include "videodir.h"
|
||||
@ -137,7 +137,7 @@ int OpenVideoFile(const char *FileName, int Flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
int Result = open(ActualFileName, Flags, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
int Result = open(ActualFileName, Flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
if (ActualFileName != FileName)
|
||||
delete ActualFileName;
|
||||
return Result;
|
||||
|
Loading…
Reference in New Issue
Block a user