2000-02-19 13:36:48 +01:00
|
|
|
/*
|
|
|
|
* dvbapi.h: Interface to the DVB driver
|
|
|
|
*
|
2000-04-24 09:46:05 +02:00
|
|
|
* See the main source file 'vdr.c' for copyright information and
|
2000-02-19 13:36:48 +01:00
|
|
|
* how to reach the author.
|
|
|
|
*
|
2002-03-10 12:45:58 +01:00
|
|
|
* $Id: dvbapi.h 1.68 2002/03/10 10:50:00 kls Exp $
|
2000-02-19 13:36:48 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __DVBAPI_H
|
|
|
|
#define __DVBAPI_H
|
|
|
|
|
2000-07-15 12:39:20 +02:00
|
|
|
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
2000-03-11 11:22:37 +01:00
|
|
|
#include <ncurses.h>
|
2002-02-03 16:47:35 +01:00
|
|
|
#undef ERR //XXX ncurses defines this - but this clashes with newer system header files
|
2000-03-11 11:22:37 +01:00
|
|
|
#endif
|
2001-06-02 10:47:40 +02:00
|
|
|
#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>
|
2000-04-15 17:38:11 +02:00
|
|
|
#include <stdio.h>
|
2001-08-03 14:18:08 +02:00
|
|
|
|
2000-10-03 10:34:48 +02:00
|
|
|
#include "dvbosd.h"
|
2000-10-29 13:17:22 +01:00
|
|
|
#include "eit.h"
|
2000-12-28 12:57:16 +01:00
|
|
|
#include "thread.h"
|
2000-03-11 11:22:37 +01:00
|
|
|
|
2001-08-11 14:30:21 +02:00
|
|
|
#define FRAMESPERSEC 25
|
|
|
|
|
2001-08-25 13:52:38 +02:00
|
|
|
// The maximum file size is limited by the range that can be covered
|
|
|
|
// with 'int'. 4GB might be possible (if the range is considered
|
|
|
|
// 'unsigned'), 2GB should be possible (even if the range is considered
|
|
|
|
// 'signed'), so let's use 2000MB for absolute safety (the actual file size
|
|
|
|
// may be slightly higher because we stop recording only before the next
|
|
|
|
// 'I' frame, to have a complete Group Of Pictures):
|
|
|
|
#define MAXVIDEOFILESIZE 2000 // MB
|
|
|
|
#define MINVIDEOFILESIZE 100 // MB
|
|
|
|
|
2002-03-09 10:07:40 +01:00
|
|
|
#define MAXVOLUME 255
|
|
|
|
#define VOLUMEDELTA 5 // used to increase/decrease the volume
|
2001-09-22 13:41:49 +02:00
|
|
|
|
2000-12-28 12:57:16 +01:00
|
|
|
const char *IndexToHMSF(int Index, bool WithFrame = false);
|
2000-12-09 11:13:00 +01:00
|
|
|
// Converts the given index to a string, optionally containing the frame number.
|
2000-12-28 12:57:16 +01:00
|
|
|
int HMSFToIndex(const char *HMSF);
|
|
|
|
// Converts the given string (format: "hh:mm:ss.ff") to an index.
|
|
|
|
|
2001-09-08 11:44:45 +02:00
|
|
|
enum eSetChannelResult { scrOk, scrNoTransfer, scrFailed };
|
|
|
|
|
2001-02-03 17:44:25 +01:00
|
|
|
class cChannel;
|
|
|
|
|
2000-12-08 16:23:32 +01:00
|
|
|
class cRecordBuffer;
|
2001-08-03 14:18:08 +02:00
|
|
|
class cPlayBuffer;
|
2000-12-08 16:23:32 +01:00
|
|
|
class cReplayBuffer;
|
2000-11-19 16:49:14 +01:00
|
|
|
class cTransferBuffer;
|
2000-12-28 12:57:16 +01:00
|
|
|
class cCuttingBuffer;
|
|
|
|
|
|
|
|
class cVideoCutter {
|
|
|
|
private:
|
2001-09-23 14:02:11 +02:00
|
|
|
static char *editedVersionName;
|
2000-12-28 12:57:16 +01:00
|
|
|
static cCuttingBuffer *cuttingBuffer;
|
2002-01-26 13:42:15 +01:00
|
|
|
static bool error;
|
|
|
|
static bool ended;
|
2000-12-28 12:57:16 +01:00
|
|
|
public:
|
|
|
|
static bool Start(const char *FileName);
|
|
|
|
static void Stop(void);
|
|
|
|
static bool Active(void);
|
2002-01-26 13:42:15 +01:00
|
|
|
static bool Error(void);
|
|
|
|
static bool Ended(void);
|
2000-12-28 12:57:16 +01:00
|
|
|
};
|
2000-11-19 16:49:14 +01:00
|
|
|
|
2000-04-15 17:38:11 +02:00
|
|
|
class cDvbApi {
|
2001-06-02 10:47:40 +02:00
|
|
|
friend class cRecordBuffer;
|
|
|
|
friend class cReplayBuffer;
|
|
|
|
friend class cTransferBuffer;
|
2000-03-11 11:22:37 +01:00
|
|
|
private:
|
2001-10-27 13:01:33 +02:00
|
|
|
FrontendType frontendType;
|
2001-09-15 14:00:14 +02:00
|
|
|
int fd_osd, fd_frontend, fd_sec, fd_dvr, fd_audio, fd_video, fd_demuxa1, fd_demuxa2, fd_demuxd1, fd_demuxd2, fd_demuxv, fd_demuxt;
|
2001-06-24 17:42:19 +02:00
|
|
|
int vPid, aPid1, aPid2, dPid1, dPid2;
|
|
|
|
bool SetPid(int fd, dmxPesType_t PesType, int Pid, dmxOutput_t Output);
|
|
|
|
bool SetVpid(int Vpid, dmxOutput_t Output) { return SetPid(fd_demuxv, DMX_PES_VIDEO, Vpid, Output); }
|
2001-06-14 15:57:30 +02:00
|
|
|
bool SetApid1(int Apid, dmxOutput_t Output) { return SetPid(fd_demuxa1, DMX_PES_AUDIO, Apid, Output); }
|
|
|
|
bool SetApid2(int Apid, dmxOutput_t Output) { return SetPid(fd_demuxa2, DMX_PES_OTHER, Apid, Output); }
|
2001-06-24 17:42:19 +02:00
|
|
|
bool SetDpid1(int Dpid, dmxOutput_t Output) { return SetPid(fd_demuxd1, DMX_PES_OTHER, Dpid, Output); }
|
|
|
|
bool SetDpid2(int Dpid, dmxOutput_t Output) { return SetPid(fd_demuxd2, DMX_PES_OTHER, Dpid, Output); }
|
|
|
|
bool SetTpid(int Tpid, dmxOutput_t Output) { return SetPid(fd_demuxt, DMX_PES_TELETEXT, Tpid, Output); }
|
2001-06-02 10:47:40 +02:00
|
|
|
bool SetPids(bool ForRecording);
|
|
|
|
cDvbApi(int n);
|
2000-02-19 13:36:48 +01:00
|
|
|
public:
|
2000-04-15 17:38:11 +02:00
|
|
|
~cDvbApi();
|
|
|
|
|
2002-03-03 16:12:29 +01:00
|
|
|
#define MAXDVBAPI 4 // the maximum number of DVB cards in the system
|
|
|
|
#define MAXCACAPS 16 // the maximum number of different CA values per DVB card
|
|
|
|
|
2000-05-01 16:29:46 +02:00
|
|
|
static int NumDvbApis;
|
|
|
|
private:
|
|
|
|
static cDvbApi *dvbApi[MAXDVBAPI];
|
2001-02-02 15:49:46 +01:00
|
|
|
static int useDvbApi;
|
2001-08-10 15:18:07 +02:00
|
|
|
int cardIndex;
|
2002-03-03 16:12:29 +01:00
|
|
|
int caCaps[MAXCACAPS];
|
|
|
|
int CanShift(int Ca, int Priority);
|
2000-05-01 16:29:46 +02:00
|
|
|
public:
|
|
|
|
static cDvbApi *PrimaryDvbApi;
|
2001-02-02 15:49:46 +01:00
|
|
|
static void SetUseDvbApi(int n);
|
|
|
|
// Sets the 'useDvbApi' flag of the given DVB device.
|
|
|
|
// If this function is not called before Init(), all DVB devices
|
|
|
|
// will be used.
|
2000-09-10 10:51:58 +02:00
|
|
|
static bool SetPrimaryDvbApi(int n);
|
|
|
|
// Sets the primary DVB device to 'n' (which must be in the range
|
|
|
|
// 1...NumDvbApis) and returns true if this was possible.
|
2000-11-12 14:06:53 +01:00
|
|
|
static cDvbApi *GetDvbApi(int Ca, int Priority);
|
2002-03-03 16:12:29 +01:00
|
|
|
// Selects a free DVB device, avoiding the PrimaryDvbApi if possible.
|
|
|
|
// If Ca is not 0, the device with the given number will be returned
|
|
|
|
// in case Ca is <= MAXDVBAPI, or the device that provides the given
|
|
|
|
// value in its caCaps.
|
2000-11-12 14:06:53 +01:00
|
|
|
// If all DVB devices are currently recording, the one recording the
|
|
|
|
// lowest priority timer (if any) that is lower than the given Priority
|
|
|
|
// will be returned.
|
|
|
|
// The caller must check whether the returned DVB device is actually
|
|
|
|
// recording and stop recording if necessary.
|
2001-08-10 15:18:07 +02:00
|
|
|
int CardIndex(void) { return cardIndex; }
|
|
|
|
// Returns the card index of this DvbApi (0 ... MAXDVBAPI - 1).
|
2002-03-08 15:19:49 +01:00
|
|
|
static void SetCaCaps(void);
|
|
|
|
// Sets the CaCaps of all DVB devices according to the Setup data.
|
2002-03-03 16:12:29 +01:00
|
|
|
int ProvidesCa(int Ca);
|
|
|
|
// Checks whether this DVB device provides the given value in its
|
|
|
|
// caCaps. Returns 0 if the value is not provided, 1 if only this
|
|
|
|
// value is provided, and > 1 if this and other values are provided.
|
|
|
|
// If the given value is equal to the number of this DVB device,
|
|
|
|
// 1 is returned. If it is 0 (FTA), 1 plus the number of other values
|
|
|
|
// in caCaps is returned.
|
2001-06-02 10:47:40 +02:00
|
|
|
static bool Probe(const char *FileName);
|
|
|
|
// Probes for existing DVB devices.
|
2000-05-01 16:29:46 +02:00
|
|
|
static bool Init(void);
|
2001-06-02 10:47:40 +02:00
|
|
|
// Initializes the DVB API.
|
2000-05-01 16:29:46 +02:00
|
|
|
// Must be called before accessing any DVB functions.
|
|
|
|
static void Cleanup(void);
|
|
|
|
// Closes down all DVB devices.
|
|
|
|
// Must be called at the end of the program.
|
|
|
|
|
2000-10-29 13:17:22 +01:00
|
|
|
// EIT facilities
|
|
|
|
|
2000-11-18 13:57:32 +01:00
|
|
|
private:
|
|
|
|
cSIProcessor *siProcessor;
|
|
|
|
public:
|
2000-09-17 11:53:35 +02:00
|
|
|
// Image Grab facilities
|
|
|
|
|
|
|
|
bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
|
|
|
|
|
2000-04-15 17:38:11 +02:00
|
|
|
// On Screen Display facilities
|
2000-02-19 13:36:48 +01:00
|
|
|
|
2000-03-11 11:22:37 +01:00
|
|
|
private:
|
|
|
|
enum { charWidth = 12, // average character width
|
|
|
|
lineHeight = 27 // smallest text height
|
|
|
|
};
|
|
|
|
#ifdef DEBUG_OSD
|
|
|
|
WINDOW *window;
|
|
|
|
enum { MaxColorPairs = 16 };
|
|
|
|
int colorPairs[MaxColorPairs];
|
|
|
|
void SetColor(eDvbColor colorFg, eDvbColor colorBg = clrBackground);
|
2000-10-03 10:34:48 +02:00
|
|
|
#else
|
|
|
|
cDvbOsd *osd;
|
2000-03-11 11:22:37 +01:00
|
|
|
#endif
|
|
|
|
int cols, rows;
|
|
|
|
public:
|
2000-04-23 15:38:16 +02:00
|
|
|
void Open(int w, int h);
|
2000-03-11 11:22:37 +01:00
|
|
|
void Close(void);
|
|
|
|
void Clear(void);
|
|
|
|
void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground);
|
2000-12-09 11:13:00 +01:00
|
|
|
void SetBitmap(int x, int y, const cBitmap &Bitmap);
|
2000-03-11 11:22:37 +01:00
|
|
|
void ClrEol(int x, int y, eDvbColor color = clrBackground);
|
2000-11-01 11:45:05 +01:00
|
|
|
int CellWidth(void);
|
2000-12-09 11:13:00 +01:00
|
|
|
int LineHeight(void);
|
2000-11-01 11:45:05 +01:00
|
|
|
int Width(unsigned char c);
|
2000-11-05 13:04:23 +01:00
|
|
|
int WidthInCells(const char *s);
|
2000-11-18 15:46:00 +01:00
|
|
|
eDvbFont SetFont(eDvbFont Font);
|
2000-03-11 11:22:37 +01:00
|
|
|
void Text(int x, int y, const char *s, eDvbColor colorFg = clrWhite, eDvbColor colorBg = clrBackground);
|
2000-10-03 10:34:48 +02:00
|
|
|
void Flush(void);
|
2000-04-15 17:38:11 +02:00
|
|
|
|
2001-06-16 14:31:14 +02:00
|
|
|
// Video format facilities:
|
|
|
|
|
|
|
|
void SetVideoFormat(videoFormat_t Format);
|
|
|
|
|
2000-04-15 17:38:11 +02:00
|
|
|
// Channel facilities
|
|
|
|
|
2000-11-05 18:39:17 +01:00
|
|
|
private:
|
|
|
|
int currentChannel;
|
|
|
|
public:
|
2001-11-24 11:42:43 +01:00
|
|
|
eSetChannelResult SetChannel(int ChannelNumber, int Frequency, char Polarization, int Diseqc, int Srate, int Vpid, int Apid1, int Apid2, int Dpid1, int Dpid2, int Tpid, int Ca, int Pnr);
|
2000-11-05 18:39:17 +01:00
|
|
|
static int CurrentChannel(void) { return PrimaryDvbApi ? PrimaryDvbApi->currentChannel : 0; }
|
2000-11-18 13:57:32 +01:00
|
|
|
int Channel(void) { return currentChannel; }
|
2000-04-15 17:38:11 +02:00
|
|
|
|
2000-11-19 16:49:14 +01:00
|
|
|
// Transfer facilities
|
|
|
|
|
|
|
|
private:
|
|
|
|
cTransferBuffer *transferBuffer;
|
|
|
|
cDvbApi *transferringFromDvbApi;
|
|
|
|
public:
|
|
|
|
bool Transferring(void);
|
|
|
|
// Returns true if we are currently transferring video data.
|
|
|
|
private:
|
|
|
|
cDvbApi *StartTransfer(int TransferToVideoDev);
|
|
|
|
// Starts transferring video data from this DVB device to TransferToVideoDev.
|
|
|
|
void StopTransfer(void);
|
|
|
|
// Stops transferring video data (in case a transfer is currently active).
|
|
|
|
|
2000-04-15 17:38:11 +02:00
|
|
|
// Record/Replay facilities
|
|
|
|
|
|
|
|
private:
|
2000-12-08 16:23:32 +01:00
|
|
|
cRecordBuffer *recordBuffer;
|
2001-08-03 14:18:08 +02:00
|
|
|
cPlayBuffer *replayBuffer;
|
2000-11-12 14:06:53 +01:00
|
|
|
int ca;
|
|
|
|
int priority;
|
2002-03-03 16:12:29 +01:00
|
|
|
int Priority(void);
|
2001-06-02 10:47:40 +02:00
|
|
|
// Returns the priority of the current recording session (0..MAXPRIORITY),
|
2002-03-03 16:12:29 +01:00
|
|
|
// or -1 if no recording is currently active. The primary DVB device will
|
|
|
|
// always return at least Setup.PrimaryLimit-1.
|
2001-06-02 10:47:40 +02:00
|
|
|
int SetModeRecord(void);
|
|
|
|
// Initiates recording mode and returns the file handle to read from.
|
|
|
|
void SetModeReplay(void);
|
|
|
|
void SetModeNormal(bool FromRecording);
|
2000-04-15 17:38:11 +02:00
|
|
|
public:
|
2001-10-28 16:32:34 +01:00
|
|
|
int Ca(void) { return ca; }
|
2002-03-03 16:12:29 +01:00
|
|
|
// Returns the ca of the current recording session.
|
2000-12-28 12:57:16 +01:00
|
|
|
int SecondsToFrames(int Seconds);
|
|
|
|
// Returns the number of frames corresponding to the given number of seconds.
|
2000-04-15 17:38:11 +02:00
|
|
|
bool Recording(void);
|
|
|
|
// Returns true if we are currently recording.
|
|
|
|
bool Replaying(void);
|
|
|
|
// Returns true if we are currently replaying.
|
2000-11-12 14:06:53 +01:00
|
|
|
bool StartRecord(const char *FileName, int Ca, int Priority);
|
|
|
|
// Starts recording the current channel into the given file, with
|
|
|
|
// the given ca and priority.
|
2000-04-15 17:38:11 +02:00
|
|
|
// In order to be able to record longer movies,
|
|
|
|
// a numerical suffix will be appended to the file name. The inital
|
|
|
|
// value of that suffix will be larger than any existing file under
|
|
|
|
// the given name, thus allowing an interrupted recording to continue
|
|
|
|
// gracefully.
|
|
|
|
// Returns true if recording was started successfully.
|
|
|
|
// If there is already a recording session active, false will be
|
|
|
|
// returned.
|
|
|
|
void StopRecord(void);
|
|
|
|
// Stops the current recording session (if any).
|
2000-12-09 11:13:00 +01:00
|
|
|
bool StartReplay(const char *FileName);
|
2000-04-15 17:38:11 +02:00
|
|
|
// Starts replaying the given file.
|
|
|
|
// If there is already a replay session active, it will be stopped
|
|
|
|
// and the new file will be played back.
|
2000-12-08 16:23:32 +01:00
|
|
|
void StopReplay(void);
|
2000-04-15 17:38:11 +02:00
|
|
|
// Stops the current replay session (if any).
|
2000-07-30 16:14:22 +02:00
|
|
|
void Pause(void);
|
2000-04-15 17:38:11 +02:00
|
|
|
// Pauses the current replay session, or resumes a paused session.
|
2000-07-30 16:14:22 +02:00
|
|
|
void Play(void);
|
|
|
|
// Resumes normal replay mode.
|
|
|
|
void Forward(void);
|
2000-04-15 17:38:11 +02:00
|
|
|
// Runs the current replay session forward at a higher speed.
|
2000-07-30 16:14:22 +02:00
|
|
|
void Backward(void);
|
2000-04-15 17:38:11 +02:00
|
|
|
// Runs the current replay session backwards at a higher speed.
|
2000-12-28 12:57:16 +01:00
|
|
|
void SkipSeconds(int Seconds);
|
2000-04-15 17:38:11 +02:00
|
|
|
// Skips the given number of seconds in the current replay session.
|
|
|
|
// The sign of 'Seconds' determines the direction in which to skip.
|
|
|
|
// Use a very large negative value to go all the way back to the
|
|
|
|
// beginning of the recording.
|
2000-12-28 12:57:16 +01:00
|
|
|
int SkipFrames(int Frames);
|
|
|
|
// Returns the new index into the current replay session after skipping
|
|
|
|
// the given number of frames (no actual repositioning is done!).
|
|
|
|
// The sign of 'Frames' determines the direction in which to skip.
|
|
|
|
bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
|
|
|
|
// Returns the current and total frame index, optionally snapped to the
|
|
|
|
// nearest I-frame.
|
2001-09-14 14:06:43 +02:00
|
|
|
bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
|
|
|
|
// Returns the current replay mode (if applicable).
|
|
|
|
// 'Play' tells whether we are playing or pausing, 'Forward' tells whether
|
|
|
|
// we are going forward or backward and 'Speed' is -1 if this is normal
|
|
|
|
// play/pause mode, 0 if it is single speed fast/slow forward/back mode
|
|
|
|
// and >0 if this is multi speed mode.
|
2001-01-07 17:00:50 +01:00
|
|
|
void Goto(int Index, bool Still = false);
|
|
|
|
// Positions to the given index and displays that frame as a still picture
|
2001-06-02 10:47:40 +02:00
|
|
|
// if Still is true.
|
2001-06-14 15:57:30 +02:00
|
|
|
|
|
|
|
// Audio track facilities
|
|
|
|
|
2001-06-24 17:42:19 +02:00
|
|
|
public:
|
2001-06-14 15:57:30 +02:00
|
|
|
bool CanToggleAudioTrack(void);
|
|
|
|
// Returns true if we are currently replaying and this recording has two
|
|
|
|
// audio tracks, or if the current channel has two audio PIDs.
|
|
|
|
bool ToggleAudioTrack(void);
|
|
|
|
// Toggles the audio track if possible.
|
2001-06-24 17:42:19 +02:00
|
|
|
|
|
|
|
// Dolby Digital audio facilities
|
|
|
|
|
|
|
|
private:
|
|
|
|
static char *audioCommand;
|
|
|
|
public:
|
|
|
|
static void SetAudioCommand(const char *Command);
|
|
|
|
static const char *AudioCommand(void) { return audioCommand; }
|
2001-09-16 15:06:54 +02:00
|
|
|
|
|
|
|
// Volume facilities:
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool mute;
|
|
|
|
int volume;
|
|
|
|
public:
|
2002-03-09 10:07:40 +01:00
|
|
|
bool IsMute(void) { return mute; }
|
2002-03-09 17:11:49 +01:00
|
|
|
bool ToggleMute(void);
|
|
|
|
// Turns the volume off or on and returns the new mute state.
|
2001-09-16 15:06:54 +02:00
|
|
|
void SetVolume(int Volume, bool Absolute = false);
|
|
|
|
// Sets the volume to the given value, either absolutely or relative to
|
|
|
|
// the current volume.
|
2001-10-27 09:57:59 +02:00
|
|
|
static int CurrentVolume(void) { return PrimaryDvbApi ? PrimaryDvbApi->volume : 0; }
|
2000-03-11 11:22:37 +01:00
|
|
|
};
|
2000-05-01 16:29:46 +02:00
|
|
|
|
2000-11-18 13:57:32 +01:00
|
|
|
class cEITScanner {
|
|
|
|
private:
|
|
|
|
enum { ActivityTimeout = 60,
|
|
|
|
ScanTimeout = 20
|
|
|
|
};
|
|
|
|
time_t lastScan, lastActivity;
|
|
|
|
int currentChannel, lastChannel;
|
2001-02-03 17:44:25 +01:00
|
|
|
int numTransponders, *transponders;
|
|
|
|
bool TransponderScanned(cChannel *Channel);
|
2000-11-18 13:57:32 +01:00
|
|
|
public:
|
|
|
|
cEITScanner(void);
|
2001-02-03 17:44:25 +01:00
|
|
|
~cEITScanner();
|
2000-11-18 13:57:32 +01:00
|
|
|
bool Active(void) { return currentChannel; }
|
|
|
|
void Activity(void);
|
|
|
|
void Process(void);
|
|
|
|
};
|
|
|
|
|
2000-02-19 13:36:48 +01:00
|
|
|
#endif //__DVBAPI_H
|