|
MythTV
0.26-pre
|
00001 #ifndef TVREC_H 00002 #define TVREC_H 00003 00004 // Qt headers 00005 #include <QWaitCondition> 00006 #include <QStringList> 00007 #include <QDateTime> 00008 #include <QRunnable> 00009 #include <QString> 00010 #include <QMap> 00011 00012 // MythTV headers 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 // locking order 00024 // stateChangeLock -> triggerEventLoopLock 00025 // -> pendingRecLock 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); // QRunnable 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 // Various components TVRec coordinates 00320 RecorderBase *recorder; 00321 ChannelBase *channel; 00322 SignalMonitor *signalMonitor; 00323 EITScanner *scanner; 00324 00325 // Various threads 00327 MThread *eventThread; 00329 MThread *recorderThread; 00330 00331 // Configuration variables from database 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 // Configuration variables from setup routines 00344 uint cardid; 00345 bool ispip; 00346 00347 // Configuration variables from database, based on cardid 00348 GeneralDBOptions genOpt; 00349 DVBDBOptions dvbOpt; 00350 FireWireDBOptions fwOpt; 00351 00352 // State variables 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 // Current recording info 00373 RecordingInfo *curRecording; 00374 QDateTime recordEndTime; 00375 int autoRunJobs; 00376 int overrecordseconds; 00377 00378 // Pending recording info 00379 PendingMap pendingRecordings; 00380 00381 // Pseudo LiveTV recording 00382 ProgramInfo *pseudoLiveTVRecording; 00383 QString nextLiveTVDir; 00384 QMutex nextLiveTVDirLock; 00385 QWaitCondition triggerLiveTVDir; 00386 QString LiveTVStartChannel; 00387 00388 // LiveTV file chain 00389 LiveTVChain *tvchain; 00390 00391 // RingBuffer info 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 // General State flags 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 // Tuning flags 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 // Non-recording Commands 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 // Waiting stuff 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 // Running stuff 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 // Tuning state 00446 static const uint kFlagRingBufferReady = 0x40000000; 00447 static const uint kFlagDetect = 0x80000000; 00448 }; 00449 00450 #endif
1.7.6.1