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