MythTV  0.26-pre
tv_rec.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends