00001 #ifndef TVREC_H
00002 #define TVREC_H
00003
00004 #include <qstring.h>
00005 #include <pthread.h>
00006 #include <qdatetime.h>
00007 #include <qvaluelist.h>
00008 #include <qptrlist.h>
00009 #include <qmap.h>
00010 #include <qstringlist.h>
00011 #include <qwaitcondition.h>
00012
00013 #include "inputinfo.h"
00014 #include "inputgroupmap.h"
00015 #include "mythdeque.h"
00016 #include "programinfo.h"
00017 #include "tv.h"
00018
00019 #include "mythconfig.h"
00020
00021 class NuppelVideoRecorder;
00022 class RingBuffer;
00023 class EITScanner;
00024 class RecordingProfile;
00025 class LiveTVChain;
00026
00027 class RecorderBase;
00028 class DTVRecorder;
00029 class DVBRecorder;
00030 class HDHRRecorder;
00031
00032 class SignalMonitor;
00033 class DTVSignalMonitor;
00034
00035 class ChannelBase;
00036 class DBox2Channel;
00037 class DTVChannel;
00038 class DVBChannel;
00039 class FirewireChannel;
00040 class Channel;
00041 class HDHRChannel;
00042
00043 class MPEGStreamData;
00044 class ProgramMapTable;
00045
00047 typedef enum
00048 {
00049 BROWSE_SAME,
00050 BROWSE_UP,
00051 BROWSE_DOWN,
00052 BROWSE_LEFT,
00053 BROWSE_RIGHT,
00054 BROWSE_FAVORITE
00055 } BrowseDirections;
00056
00057 class GeneralDBOptions
00058 {
00059 public:
00060 GeneralDBOptions() :
00061 videodev(""), vbidev(""),
00062 audiodev(""), defaultinput("Television"),
00063 cardtype("V4L"),
00064 audiosamplerate(-1), skip_btaudio(false),
00065 signal_timeout(1000), channel_timeout(3000) {;}
00066
00067 QString videodev;
00068 QString vbidev;
00069 QString audiodev;
00070 QString defaultinput;
00071 QString cardtype;
00072 int audiosamplerate;
00073 bool skip_btaudio;
00074 uint signal_timeout;
00075 uint channel_timeout;
00076 bool wait_for_seqstart;
00077 };
00078
00079 class DVBDBOptions
00080 {
00081 public:
00082 DVBDBOptions() : dvb_on_demand(false), dvb_tuning_delay(0), dvb_eitscan(true) {;}
00083 bool dvb_on_demand;
00084 uint dvb_tuning_delay;
00085 bool dvb_eitscan;
00086 };
00087
00088 class FireWireDBOptions
00089 {
00090 public:
00091 FireWireDBOptions() : speed(-1), connection(-1), model("") {;}
00092
00093 int speed;
00094 int connection;
00095 QString model;
00096 };
00097
00098 class DBox2DBOptions
00099 {
00100 public:
00101 DBox2DBOptions() : port(-1), httpport(-1), host("") {;}
00102
00103 int port;
00104 int httpport;
00105 QString host;
00106 };
00107
00108 class TuningRequest
00109 {
00110 public:
00111 TuningRequest(uint f) :
00112 flags(f), program(NULL), channel(QString::null),
00113 input(QString::null), majorChan(0), minorChan(0), progNum(-1) {;}
00114 TuningRequest(uint f, ProgramInfo *p) :
00115 flags(f), program(p), channel(QString::null),
00116 input(QString::null), majorChan(0), minorChan(0), progNum(-1) {;}
00117 TuningRequest(uint f, QString ch, QString in = QString::null) :
00118 flags(f), program(NULL), channel(ch),
00119 input(in), majorChan(0), minorChan(0), progNum(-1) {;}
00120
00121 QString toString(void) const;
00122
00123 bool IsOnSameMultiplex(void) const { return minorChan || (progNum >= 0); }
00124
00125 public:
00126 uint flags;
00127 ProgramInfo *program;
00128 QString channel;
00129 QString input;
00130 uint majorChan;
00131 uint minorChan;
00132 int progNum;
00133 };
00134 typedef MythDeque<TuningRequest> TuningQueue;
00135
00136 class PendingInfo
00137 {
00138 public:
00139 PendingInfo() :
00140 info(NULL), hasLaterShowing(false), canceled(false),
00141 ask(false), doNotAsk(false) { }
00142 ProgramInfo *info;
00143 QDateTime recordingStart;
00144 bool hasLaterShowing;
00145 bool canceled;
00146 bool ask;
00147 bool doNotAsk;
00148 vector<uint> possibleConflicts;
00149 };
00150 typedef QMap<uint,PendingInfo> PendingMap;
00151
00152 class MPUBLIC TVRec : public QObject
00153 {
00154 friend class TuningRequest;
00155 Q_OBJECT
00156 public:
00157 TVRec(int capturecardnum);
00158 ~TVRec(void);
00159
00160 bool Init(void);
00161
00162 void RecordPending(const ProgramInfo *rcinfo, int secsleft, bool hasLater);
00163 RecStatusType StartRecording(const ProgramInfo *rcinfo);
00164
00165 void StopRecording(void);
00167 void FinishRecording(void) { SetFlags(kFlagFinishRecording); }
00169 void FrontendReady(void) { SetFlags(kFlagFrontendReady); }
00170 void CancelNextRecording(bool cancel);
00171 ProgramInfo *GetRecording(void);
00172
00174 bool IsRunning(void) const { return HasFlags(kFlagRunMainLoop); }
00176 void Stop(void) { ClearFlags(kFlagRunMainLoop); }
00177
00178 TVState GetState(void) const;
00180 bool IsPlaying(void) { return StateIsPlaying(internalState); }
00183 bool IsRecording(void) { return StateIsRecording(internalState); }
00184
00185 bool SetVideoFiltersForChannel(uint sourceid, const QString &channum);
00186
00187 bool IsBusy(TunedInputInfo *busy_input = NULL, int time_buffer = 5) const;
00188 bool IsReallyRecording(void);
00189
00190 float GetFramerate(void);
00191 long long GetFramesWritten(void);
00192 long long GetFilePosition(void);
00193 long long GetMaxBitrate();
00194 long long GetKeyframePosition(long long desired);
00195 void SpawnLiveTV(LiveTVChain *newchain, bool pip, QString startchan);
00196 QString GetChainID(void);
00197 void StopLiveTV(void);
00198 void PauseRecorder(void);
00199 void ToggleChannelFavorite(void);
00200
00201 void SetLiveRecording(int recording);
00202
00203 vector<InputInfo> GetFreeInputs(const vector<uint> &excluded_cards) const;
00204 QString GetInput(void) const;
00205 QString SetInput(QString input, uint requestType = kFlagDetect);
00206
00208 void ChangeChannel(ChannelChangeDirection dir)
00209 { SetChannel(QString("NextChannel %1").arg((int)dir)); }
00210 void SetChannel(QString name, uint requestType = kFlagDetect);
00211
00212 int SetSignalMonitoringRate(int msec, int notifyFrontend = 1);
00213 int GetPictureAttribute(PictureAttribute attr);
00214 int ChangePictureAttribute(PictureAdjustType type, PictureAttribute attr,
00215 bool direction);
00216 bool CheckChannel(QString name) const;
00217 bool ShouldSwitchToAnotherCard(QString chanid);
00218 bool CheckChannelPrefix(const QString&,uint&,bool&,QString&);
00219 void GetNextProgram(int direction,
00220 QString &title, QString &subtitle,
00221 QString &desc, QString &category,
00222 QString &starttime, QString &endtime,
00223 QString &callsign, QString &iconpath,
00224 QString &channelname, QString &chanid,
00225 QString &seriesid, QString &programid);
00226 bool GetChannelInfo(uint &chanid, uint &sourceid,
00227 QString &callsign, QString &channum,
00228 QString &channame, QString &xmltvid) const;
00229 bool SetChannelInfo(uint chanid, uint sourceid, QString oldchannum,
00230 QString callsign, QString channum,
00231 QString channame, QString xmltvid);
00232
00234 int GetCaptureCardNum(void) { return cardid; }
00236 bool IsErrored(void) const { return HasFlags(kFlagErrored); }
00237
00238 void RingBufferChanged(RingBuffer *rb, ProgramInfo *pginfo);
00239 void RecorderPaused(void);
00240
00241 void SetNextLiveTVDir(QString dir);
00242
00243 uint GetFlags(void) const { return stateFlags; }
00244
00245 static TVRec *GetTVRec(uint cardid);
00246
00247 public slots:
00248 void SignalMonitorAllGood() { triggerEventLoop.wakeAll(); }
00249 void deleteLater(void);
00250
00251 protected:
00252 void RunTV(void);
00253 bool WaitForEventThreadSleep(bool wake = true, ulong time = ULONG_MAX);
00254 static void *EventThread(void *param);
00255 static void *RecorderThread(void *param);
00256
00257 private:
00258 void SetRingBuffer(RingBuffer *);
00259 void SetPseudoLiveTVRecording(ProgramInfo*);
00260 void TeardownAll(void);
00261
00262 static bool GetDevices(int cardid,
00263 GeneralDBOptions &general_opts,
00264 DVBDBOptions &dvb_opts,
00265 FireWireDBOptions &firewire_opts,
00266 DBox2DBOptions &dbox2_opts);
00267
00268 static QString GetStartChannel(int cardid, const QString &defaultinput);
00269
00270 bool SetupRecorder(RecordingProfile& profile);
00271 void TeardownRecorder(bool killFile = false);
00272 DTVRecorder *GetDTVRecorder(void);
00273 HDHRRecorder *GetHDHRRecorder(void);
00274 DVBRecorder *GetDVBRecorder(void);
00275
00276 bool CreateChannel(const QString &startChanNum);
00277 void InitChannel(const QString &inputname, const QString &startchannel);
00278 void CloseChannel(void);
00279 DBox2Channel *GetDBox2Channel(void);
00280 DTVChannel *GetDTVChannel(void);
00281 HDHRChannel *GetHDHRChannel(void);
00282 DVBChannel *GetDVBChannel(void);
00283 FirewireChannel *GetFirewireChannel(void);
00284 Channel *GetV4LChannel(void);
00285
00286 bool SetupSignalMonitor(bool enable_table_monitoring, bool notify);
00287 bool SetupDTVSignalMonitor(void);
00288 void TeardownSignalMonitor(void);
00289 DTVSignalMonitor *GetDTVSignalMonitor(void);
00290
00291 bool HasFlags(uint f) const { return (stateFlags & f) == f; }
00292 void SetFlags(uint f);
00293 void ClearFlags(uint f);
00294 static QString FlagToString(uint);
00295
00296 void HandleTuning(void);
00297 void TuningShutdowns(const TuningRequest&);
00298 void TuningFrequency(const TuningRequest&);
00299 MPEGStreamData *TuningSignalCheck(void);
00300
00301 void TuningNewRecorder(MPEGStreamData*);
00302 void TuningRestartRecorder(void);
00303 QString TuningGetChanNum(const TuningRequest&, QString &input) const;
00304 uint TuningCheckForHWChange(const TuningRequest&,
00305 QString &channum,
00306 QString &inputname);
00307 bool TuningOnSameMultiplex(TuningRequest &request);
00308
00309 void HandleStateChange(void);
00310 void ChangeState(TVState nextState);
00311 bool StateIsRecording(TVState state);
00312 bool StateIsPlaying(TVState state);
00313 TVState RemovePlaying(TVState state);
00314 TVState RemoveRecording(TVState state);
00315
00316 void HandlePendingRecordings(void);
00317
00318 bool WaitForNextLiveTVDir(void);
00319 bool GetProgramRingBufferForLiveTV(ProgramInfo **pginfo, RingBuffer **rb);
00320 bool CreateLiveTVRingBuffer(void);
00321 bool SwitchLiveTVRingBuffer(bool discont = false, bool set_rec = true);
00322
00323 void StartedRecording(ProgramInfo*);
00324 void FinishedRecording(ProgramInfo*);
00325 QDateTime GetRecordEndTime(const ProgramInfo*) const;
00326 void CheckForRecGroupChange(void);
00327 void NotifySchedulerOfRecording(ProgramInfo*);
00328
00329
00330 RecorderBase *recorder;
00331 ChannelBase *channel;
00332 SignalMonitor *signalMonitor;
00333 EITScanner *scanner;
00334
00335
00337 pthread_t event_thread;
00339 pthread_t recorder_thread;
00340
00341
00342 bool eitIgnoresSource;
00343 bool transcodeFirst;
00344 bool earlyCommFlag;
00345 bool runJobOnHostOnly;
00346 int eitCrawlIdleStart;
00347 int eitTransportTimeout;
00348 int audioSampleRateDB;
00349 int overRecordSecNrml;
00350 int overRecordSecCat;
00351 QString overRecordCategory;
00352 InputGroupMap igrp;
00353
00354
00355 int cardid;
00356 bool ispip;
00357
00358
00359 GeneralDBOptions genOpt;
00360 DVBDBOptions dvbOpt;
00361 FireWireDBOptions fwOpt;
00362 DBox2DBOptions dboxOpt;
00363
00364
00365 mutable QMutex stateChangeLock;
00366 TVState internalState;
00367 TVState desiredNextState;
00368 bool changeState;
00369 bool pauseNotify;
00370 uint stateFlags;
00371 TuningQueue tuningRequests;
00372 TuningRequest lastTuningRequest;
00373 QDateTime eitScanStartTime;
00374 QWaitCondition triggerEventLoop;
00375 QWaitCondition triggerEventSleep;
00376 bool m_switchingBuffer;
00377
00378
00379 ProgramInfo *curRecording;
00380 QDateTime recordEndTime;
00381 int autoRunJobs;
00382 int overrecordseconds;
00383
00384
00385 PendingMap pendingRecordings;
00386
00387
00388 ProgramInfo *pseudoLiveTVRecording;
00389 QString nextLiveTVDir;
00390 QMutex nextLiveTVDirLock;
00391 QString LiveTVStartChannel;
00392
00393
00394 LiveTVChain *tvchain;
00395
00396
00397 RingBuffer *ringBuffer;
00398 QString rbFileExt;
00399
00400 static QMutex cardsLock;
00401 static QMap<uint,TVRec*> cards;
00402
00403 public:
00404 static const uint kSignalMonitoringRate;
00405
00406
00407 static const uint kFlagFrontendReady = 0x00000001;
00408 static const uint kFlagRunMainLoop = 0x00000002;
00409 static const uint kFlagExitPlayer = 0x00000004;
00410 static const uint kFlagFinishRecording = 0x00000008;
00411 static const uint kFlagErrored = 0x00000010;
00412 static const uint kFlagCancelNextRecording = 0x00000020;
00413
00414
00416 static const uint kFlagLiveTV = 0x00000100;
00418 static const uint kFlagRecording = 0x00000200;
00420 static const uint kFlagAntennaAdjust = 0x00000400;
00421 static const uint kFlagRec = 0x00000F00;
00422
00423
00425 static const uint kFlagEITScan = 0x00001000;
00427 static const uint kFlagCloseRec = 0x00002000;
00429 static const uint kFlagKillRec = 0x00004000;
00430
00431 static const uint kFlagNoRec = 0x0000F000;
00432 static const uint kFlagKillRingBuffer = 0x00010000;
00433
00434
00435 static const uint kFlagWaitingForRecPause = 0x00100000;
00436 static const uint kFlagWaitingForSignal = 0x00200000;
00437 static const uint kFlagNeedToStartRecorder = 0x00800000;
00438 static const uint kFlagPendingActions = 0x00F00000;
00439
00440
00441 static const uint kFlagSignalMonitorRunning = 0x01000000;
00442 static const uint kFlagEITScannerRunning = 0x04000000;
00443
00444 static const uint kFlagDummyRecorderRunning = 0x10000000;
00445 static const uint kFlagRecorderRunning = 0x20000000;
00446 static const uint kFlagAnyRecRunning = 0x30000000;
00447 static const uint kFlagAnyRunning = 0x3F000000;
00448
00449
00450 static const uint kFlagRingBufferReady = 0x40000000;
00451 static const uint kFlagDetect = 0x80000000;
00452 };
00453
00454 #endif