MythTV  master
tv_rec.h
Go to the documentation of this file.
1 #ifndef TVREC_H
2 #define TVREC_H
3 
4 // Qt headers
5 #include <QWaitCondition>
6 #include <QStringList>
7 #include <QDateTime>
8 #include <QRunnable>
9 #include <QString>
10 #include <QMap>
11 #include <QMutex> // for QMutex
12 #include <QReadWriteLock>
13 #include <QHash> // for QHash
14 
15 // C++ headers
16 #include <vector> // for vector
17 
18 // MythTV headers
19 #include "mythtimer.h"
20 #include "mthread.h"
21 #include "inputinfo.h"
22 #include "mythdeque.h"
23 
24 #include "recordinginfo.h"
25 #include "tv.h"
26 #include "signalmonitorlistener.h"
27 #include "mythtvexp.h" // for MTV_PUBLIC
28 #include "programtypes.h" // for RecStatus, RecStatus::Type, etc
29 #include "videoouttypes.h" // for PictureAttribute
30 
31 #include "mythconfig.h"
32 
33 // locking order
34 // setChannelLock -> stateChangeLock -> triggerEventLoopLock
35 // -> pendingRecLock
36 
37 class RingBuffer;
38 class EITScanner;
39 class RecordingProfile;
40 class LiveTVChain;
41 
42 class RecorderBase;
43 class DTVRecorder;
44 class DVBRecorder;
45 class HDHRRecorder;
46 class ASIRecorder;
47 class CetonRecorder;
48 
49 class SignalMonitor;
50 class DTVSignalMonitor;
51 
52 class ChannelBase;
53 class DTVChannel;
54 class DVBChannel;
55 class FirewireChannel;
56 class V4LChannel;
57 class HDHRChannel;
58 class CetonChannel;
59 
60 class MPEGStreamData;
61 class ProgramMapTable;
62 class RecordingQuality;
63 
65 {
66  public:
67  GeneralDBOptions()= default;
68 
69  QString m_videoDev;
70  QString m_vbiDev;
71  QString m_audioDev;
72  QString m_inputType {"V4L"};
74  bool m_skipBtAudio {false};
77  bool m_waitForSeqstart {false};
78 };
79 
81 {
82  public:
83  DVBDBOptions() = default;
84 
85  bool m_dvbOnDemand {false};
87  bool m_dvbEitScan {true};
88 };
89 
91 {
92  public:
93  FireWireDBOptions() = default;
94 
95  int m_speed {-1};
96  int m_connection {-1};
97  QString m_model;
98 };
99 
101 {
102  public:
103  explicit TuningRequest(uint f) :
104  m_flags(f) {;}
106  m_flags(f), m_program(p) {;}
107  TuningRequest(uint f, const QString& ch, const QString& in = QString()) :
108  m_flags(f), m_channel(ch), m_input(in) {;}
109 
110  QString toString(void) const;
111 
112  bool IsOnSameMultiplex(void) const { return m_minorChan || (m_progNum >= 0); }
113 
114  public:
117  QString m_channel;
118  QString m_input;
121  int m_progNum {-1};
122 };
125 
127 {
128  public:
129  PendingInfo() = default;
130 
131  ProgramInfo *m_info {nullptr};
132  QDateTime m_recordingStart;
133  bool m_hasLaterShowing {false};
134  bool m_canceled {false};
135  bool m_ask {false};
136  bool m_doNotAsk {false};
137  vector<uint> m_possibleConflicts;
138 };
139 using PendingMap = QMap<uint,PendingInfo>;
140 
141 class MTV_PUBLIC TVRec : public SignalMonitorListener, public QRunnable
142 {
143  Q_DECLARE_TR_FUNCTIONS(TVRec)
144 
145  friend class TuningRequest;
146  friend class TVRecRecordThread;
147 
148  public:
149  explicit TVRec(int _inputid);
150  ~TVRec(void);
151 
152  bool Init(void);
153 
154  void RecordPending(const ProgramInfo *rcinfo, int secsleft, bool hasLater);
155  RecStatus::Type StartRecording(ProgramInfo *pginfo);
156  RecStatus::Type GetRecordingStatus(void) const;
157 
158  void StopRecording(bool killFile = false);
160  void FinishRecording(void) { SetFlags(kFlagFinishRecording,
161  __FILE__, __LINE__); }
163  void FrontendReady(void) { SetFlags(kFlagFrontendReady,
164  __FILE__, __LINE__); }
165  void CancelNextRecording(bool cancel);
166  ProgramInfo *GetRecording(void);
167 
169  bool IsRunning(void) const { return HasFlags(kFlagRunMainLoop); }
171  void Stop(void) { ClearFlags(kFlagRunMainLoop, __FILE__, __LINE__); }
172 
173  TVState GetState(void) const;
175  bool IsPlaying(void) { return StateIsPlaying(m_internalState); }
178  bool IsRecording(void) { return StateIsRecording(m_internalState); }
179 
180  bool SetVideoFiltersForChannel(uint sourceid, const QString &channum);
181 
182  bool IsBusy(InputInfo *busy_input = nullptr, int time_buffer = 5) const;
183  bool IsReallyRecording(void);
184 
185  float GetFramerate(void);
186  long long GetFramesWritten(void);
187  long long GetFilePosition(void);
188  long long GetMaxBitrate(void) const;
189  int64_t GetKeyframePosition(uint64_t desired) const;
190  bool GetKeyframePositions(int64_t start, int64_t end, frm_pos_map_t&) const;
191  bool GetKeyframeDurations(int64_t start, int64_t end, frm_pos_map_t&) const;
192  void SpawnLiveTV(LiveTVChain *newchain, bool pip, QString startchan);
193  QString GetChainID(void);
194  void StopLiveTV(void);
195  void PauseRecorder(void);
196  void ToggleChannelFavorite(const QString&);
197 
198  void SetLiveRecording(int recording);
199 
200  QString GetInput(void) const;
201  uint GetSourceID(void) const;
202  QString SetInput(QString input);
203 
206  { SetChannel(QString("NextChannel %1").arg((int)dir)); }
207  void SetChannel(const QString& name, uint requestType = kFlagDetect);
208  bool QueueEITChannelChange(const QString &name);
209 
210  int SetSignalMonitoringRate(int rate, int notifyFrontend = 1);
211  int GetPictureAttribute(PictureAttribute attr);
212  int ChangePictureAttribute(PictureAdjustType type, PictureAttribute attr,
213  bool direction);
214  bool CheckChannel(const QString& name) const;
215  bool ShouldSwitchToAnotherInput(const QString& chanid);
216  bool CheckChannelPrefix(const QString&,uint&,bool&,QString&);
217  void GetNextProgram(BrowseDirection direction,
218  QString &title, QString &subtitle,
219  QString &desc, QString &category,
220  QString &starttime, QString &endtime,
221  QString &callsign, QString &iconpath,
222  QString &channum, uint &chanid,
223  QString &seriesid, QString &programid);
224  bool GetChannelInfo(uint &chanid, uint &sourceid,
225  QString &callsign, QString &channum,
226  QString &channame, QString &xmltvid) const;
227  bool SetChannelInfo(uint chanid, uint sourceid, const QString& oldchannum,
228  const QString& callsign, const QString& channum,
229  const QString& channame, const QString& xmltvid);
230 
232  uint GetInputId(void) { return m_inputid; }
233  uint GetParentId(void) { return m_parentid; }
234  uint GetMajorId(void) { return m_parentid ? m_parentid : m_inputid; }
236  bool IsErrored(void) const { return HasFlags(kFlagErrored); }
237 
238  void RingBufferChanged(RingBuffer*, RecordingInfo*, RecordingQuality*);
239  void RecorderPaused(void);
240 
241  void SetNextLiveTVDir(QString dir);
242 
243  uint GetFlags(void) const { return m_stateFlags; }
244 
245  static TVRec *GetTVRec(uint inputid);
246 
247  void AllGood(void) override { WakeEventLoop(); } // SignalMonitorListener
248  void StatusChannelTuned(const SignalMonitorValue&) override { } // SignalMonitorListener
249  void StatusSignalLock(const SignalMonitorValue&) override { } // SignalMonitorListener
250  void StatusSignalStrength(const SignalMonitorValue&) override { } // SignalMonitorListener
251 
252  protected:
253  void run(void) override; // QRunnable
254  bool WaitForEventThreadSleep(bool wake = true, ulong time = ULONG_MAX);
255 
256  private:
257  void SetRingBuffer(RingBuffer *);
258  void SetPseudoLiveTVRecording(RecordingInfo*);
259  void TeardownAll(void);
260  void WakeEventLoop(void);
261 
262  static bool GetDevices(uint inputid,
263  uint &parentid,
264  GeneralDBOptions &gen_opts,
265  DVBDBOptions &dvb_opts,
266  FireWireDBOptions &firewire_opts);
267 
268  static QString GetStartChannel(uint inputid);
269 
270  void TeardownRecorder(uint request_flags);
271  DTVRecorder *GetDTVRecorder(void);
272 
273  bool CreateChannel(const QString &startchannel,
274  bool enter_power_save_mode);
275  void CloseChannel(void);
276  DTVChannel *GetDTVChannel(void);
277  V4LChannel *GetV4LChannel(void);
278 
279  bool SetupSignalMonitor(
280  bool tablemon, bool EITscan, bool notify);
281  bool SetupDTVSignalMonitor(bool EITscan);
282  void TeardownSignalMonitor(void);
283  DTVSignalMonitor *GetDTVSignalMonitor(void);
284 
285  bool HasFlags(uint f) const { return (m_stateFlags & f) == f; }
286  void SetFlags(uint f, const QString & file, int line);
287  void ClearFlags(uint f, const QString & file, int line);
288  static QString FlagToString(uint);
289 
290  void HandleTuning(void);
291  void TuningShutdowns(const TuningRequest&);
292  void TuningFrequency(const TuningRequest&);
293  MPEGStreamData *TuningSignalCheck(void);
294 
295  void TuningNewRecorder(MPEGStreamData*);
296  void TuningRestartRecorder(void);
297  QString TuningGetChanNum(const TuningRequest&, QString &input) const;
298  bool TuningOnSameMultiplex(TuningRequest &request);
299 
300  void HandleStateChange(void);
301  void ChangeState(TVState nextState);
302  static bool StateIsRecording(TVState state);
303  static bool StateIsPlaying(TVState state);
304  TVState RemovePlaying(TVState state);
305  TVState RemoveRecording(TVState state);
306 
307  void HandlePendingRecordings(void);
308 
309  bool WaitForNextLiveTVDir(void);
310  bool GetProgramRingBufferForLiveTV(RecordingInfo **pginfo, RingBuffer **rb,
311  const QString &channum);
312  bool CreateLiveTVRingBuffer(const QString & channum);
313  bool SwitchLiveTVRingBuffer(const QString & channum,
314  bool discont, bool set_rec);
315 
316  RecordingInfo *SwitchRecordingRingBuffer(const RecordingInfo &rcinfo);
317 
318  void StartedRecording(RecordingInfo*);
319  void FinishedRecording(RecordingInfo*, RecordingQuality*);
320  QDateTime GetRecordEndTime(const ProgramInfo*) const;
321  void CheckForRecGroupChange(void);
322  void NotifySchedulerOfRecording(RecordingInfo*);
323  enum AutoRunInitType { kAutoRunProfile, kAutoRunNone, };
324  void InitAutoRunJobs(RecordingInfo*, AutoRunInitType,
325  RecordingProfile *, int line);
326 
327  void SetRecordingStatus(
328  RecStatus::Type new_status, int line, bool have_lock = false);
329 
330  QString LoadProfile(void*, RecordingInfo*,
332 
333  // Various components TVRec coordinates
334  RecorderBase *m_recorder {nullptr};
335  ChannelBase *m_channel {nullptr};
336  SignalMonitor *m_signalMonitor {nullptr};
337  EITScanner *m_scanner {nullptr};
338 
340  bool m_signalEventCmdSent {false};
341 
344  uint m_signalMonitorCheckCnt {0};
345  bool m_reachedRecordingDeadline {false};
346  QDateTime m_preFailDeadline;
347  bool m_reachedPreFail {false};
348 
349  // Various threads
351  MThread *m_eventThread {nullptr};
353  MThread *m_recorderThread {nullptr};
354 
355  // Configuration variables from database
356  bool m_transcodeFirst {false};
357  bool m_earlyCommFlag {false};
358  bool m_runJobOnHostOnly {false};
359  int m_eitCrawlIdleStart {60};
360  int m_eitTransportTimeout {5*60};
361  int m_audioSampleRateDB {0};
362  int m_overRecordSecNrml {0};
363  int m_overRecordSecCat {0};
365 
366  // Configuration variables from setup routines
368  uint m_parentid {0};
369  bool m_ispip {false};
370 
371  // Configuration variables from database, based on inputid
375 
377 
378  // State variables
379  mutable QMutex m_setChannelLock;
380  mutable QMutex m_stateChangeLock {QMutex::Recursive};
381  mutable QMutex m_pendingRecLock {QMutex::Recursive};
382  TVState m_internalState {kState_None};
383  TVState m_desiredNextState {kState_None};
384  bool m_changeState {false};
385  bool m_pauseNotify {true};
386  uint m_stateFlags {0};
388  TuningRequest m_lastTuningRequest {0};
390  mutable QMutex m_triggerEventLoopLock {QMutex::NonRecursive};
391  QWaitCondition m_triggerEventLoopWait;
392  bool m_triggerEventLoopSignal {false};
393  mutable QMutex m_triggerEventSleepLock {QMutex::NonRecursive};
394  QWaitCondition m_triggerEventSleepWait;
395  bool m_triggerEventSleepSignal {false};
396  volatile bool m_switchingBuffer {false};
398 
399  // Current recording info
400  RecordingInfo *m_curRecording {nullptr};
401  QDateTime m_recordEndTime;
402  // RecordingInfo::MakeUniqueKey()->autoRun
403  QHash<QString,int> m_autoRunJobs;
404  int m_overrecordseconds {0};
405 
406  // Pending recording info
408 
409  // Pseudo LiveTV recording
410  RecordingInfo *m_pseudoLiveTVRecording {nullptr};
413  QWaitCondition m_triggerLiveTVDir;
415 
416  // LiveTV file chain
417  LiveTVChain *m_tvChain {nullptr};
418 
419  // RingBuffer info
420  RingBuffer *m_ringBuffer {nullptr};
421  QString m_rbFileExt {"ts"};
422 
423  public:
424  static QReadWriteLock s_inputsLock;
425  static QMap<uint,TVRec*> s_inputs;
426 
427  public:
429 
430  // General State flags
431  static const uint kFlagFrontendReady = 0x00000001;
432  static const uint kFlagRunMainLoop = 0x00000002;
433  static const uint kFlagExitPlayer = 0x00000004;
434  static const uint kFlagFinishRecording = 0x00000008;
435  static const uint kFlagErrored = 0x00000010;
436  static const uint kFlagCancelNextRecording = 0x00000020;
437 
438  // Tuning flags
440  static const uint kFlagLiveTV = 0x00000100;
442  static const uint kFlagRecording = 0x00000200;
444  static const uint kFlagAntennaAdjust = 0x00000400;
445  static const uint kFlagRec = 0x00000F00;
446 
447  // Non-recording Commands
449  static const uint kFlagEITScan = 0x00001000;
451  static const uint kFlagCloseRec = 0x00002000;
453  static const uint kFlagKillRec = 0x00004000;
454 
455  static const uint kFlagNoRec = 0x0000F000;
456  static const uint kFlagKillRingBuffer = 0x00010000;
457 
458  // Waiting stuff
459  static const uint kFlagWaitingForRecPause = 0x00100000;
460  static const uint kFlagWaitingForSignal = 0x00200000;
461  static const uint kFlagNeedToStartRecorder = 0x00800000;
462  static const uint kFlagPendingActions = 0x00F00000;
463 
464  // Running stuff
465  static const uint kFlagSignalMonitorRunning = 0x01000000;
466  static const uint kFlagEITScannerRunning = 0x04000000;
467 
468  static const uint kFlagDummyRecorderRunning = 0x10000000;
469  static const uint kFlagRecorderRunning = 0x20000000;
470  static const uint kFlagAnyRecRunning = 0x30000000;
471  static const uint kFlagAnyRunning = 0x3F000000;
472 
473  // Tuning state
474  static const uint kFlagRingBufferReady = 0x40000000;
475  static const uint kFlagDetect = 0x80000000;
476 };
477 
478 #endif
bool IsPlaying(void)
Returns "state == kState_RecordingPreRecorded".
Definition: tv_rec.h:175
QWaitCondition m_triggerLiveTVDir
Definition: tv_rec.h:413
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:46
ProgramInfo * m_info
Definition: tv_rec.h:131
This is a specialization of RecorderBase used to handle MPEG-2, MPEG-4, MPEG-4 AVC,...
Definition: dtvrecorder.h:28
uint GetInputId(void)
Returns the inputid.
Definition: tv_rec.h:232
ChannelChangeDirection
ChannelChangeDirection is an enumeration of possible channel changing directions.
Definition: tv.h:28
AutoRunInitType
Definition: tv_rec.h:323
This is a specialization of DTVRecorder used to handle streams from DVB drivers.
Definition: dvbrecorder.h:21
QString m_recProfileName
Definition: tv_rec.h:376
TuningRequest(uint f)
Definition: tv_rec.h:103
uint m_majorChan
Definition: tv_rec.h:119
void AllGood(void) override
Signal to be sent when you have a lock on all values.
Definition: tv_rec.h:247
bool m_skipBtAudio
Definition: tv_rec.h:74
QString m_input
Definition: tv_rec.h:118
QString m_videoDev
Definition: tv_rec.h:69
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:34
PendingInfo()=default
uint GetMajorId(void)
Definition: tv_rec.h:234
RecordingInfo * m_program
Definition: tv_rec.h:116
QString m_overRecordCategory
Definition: tv_rec.h:364
Provides interface to the tuning hardware when using DVB drivers.
Definition: dvbchannel.h:29
bool m_hasLaterShowing
Definition: tv_rec.h:133
void ChangeChannel(ChannelChangeDirection dir)
Changes to a channel in the 'dir' channel change direction.
Definition: tv_rec.h:205
vector< uint > m_possibleConflicts
Definition: tv_rec.h:137
void StatusChannelTuned(const SignalMonitorValue &) override
Signal to be sent with change change status.
Definition: tv_rec.h:248
void FrontendReady(void)
Tells TVRec that the frontend's TV class is ready for messages.
Definition: tv_rec.h:163
QMap< uint, PendingInfo > PendingMap
Definition: tv_rec.h:139
QDateTime m_recordEndTime
Definition: tv_rec.h:401
bool IsOnSameMultiplex(void) const
Definition: tv_rec.h:112
TVState
TVState is an enumeration of the states used by TV and TVRec.
Definition: tv.h:50
int m_audioSampleRate
Definition: tv_rec.h:73
PendingMap m_pendingRecordings
Definition: tv_rec.h:407
int m_progNum
Definition: tv_rec.h:121
void StatusSignalLock(const SignalMonitorValue &) override
Signal to be sent as true when it is safe to begin or continue recording, and false if it may not be ...
Definition: tv_rec.h:249
uint GetParentId(void)
Definition: tv_rec.h:233
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
Definition: programtypes.h:46
uint m_inputid
Definition: tv_rec.h:367
Holds information on recordings and videos.
Definition: programinfo.h:66
QDateTime m_eitScanStartTime
Definition: tv_rec.h:389
QMutex m_setChannelLock
Definition: tv_rec.h:379
static QReadWriteLock s_inputsLock
Definition: tv_rec.h:424
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
QString m_audioDev
Definition: tv_rec.h:71
QString m_nextLiveTVDir
Definition: tv_rec.h:411
QHash< QString, int > m_autoRunJobs
Definition: tv_rec.h:403
QWaitCondition m_triggerEventSleepWait
Definition: tv_rec.h:394
Class providing a generic interface to digital tuning hardware.
Definition: dtvchannel.h:34
bool m_dvbOnDemand
Definition: tv_rec.h:85
#define MTV_PUBLIC
Definition: mythtvexp.h:15
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:141
TuningRequest myth_deque_init(const TuningRequest *)
Definition: tv_rec.h:124
bool m_waitForSeqstart
Definition: tv_rec.h:77
#define GetState(a, b)
uint m_minorChan
Definition: tv_rec.h:120
FirewireChannel Copyright (c) 2005 by Jim Westfall and Dave Abrahams Distributed as part of MythTV un...
void Stop(void)
Tells TVRec to stop event loop.
Definition: tv_rec.h:171
uint m_signalTimeout
Definition: tv_rec.h:75
QMutex m_nextLiveTVDirLock
Definition: tv_rec.h:412
uint m_flags
Definition: tv_rec.h:115
QDateTime m_signalEventCmdTimeout
Definition: tv_rec.h:339
Acts as glue between ChannelBase, EITSource, and EITHelper.
Definition: eitscanner.h:30
static const uint kSignalMonitoringRate
How many milliseconds the signal monitor should wait between checks.
Definition: tv_rec.h:428
PictureAttribute
Definition: videoouttypes.h:89
unsigned int uint
Definition: compat.h:140
Implements tuning for TV cards using the V4L driver API, both versions 1 and 2.
Definition: v4lchannel.h:32
uint m_dvbTuningDelay
Definition: tv_rec.h:86
QString m_liveTVStartChannel
Definition: tv_rec.h:414
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:66
void StatusSignalStrength(const SignalMonitorValue &) override
Signal to be sent with an actual signal value.
Definition: tv_rec.h:250
TuningRequest(uint f, const QString &ch, const QString &in=QString())
Definition: tv_rec.h:107
QDateTime m_signalMonitorDeadline
Definition: tv_rec.h:343
FireWireDBOptions()=default
This is a specialization of DTVRecorder used to handle streams from ASI drivers.
Definition: asirecorder.h:55
None State, this is the initial state in both TV and TVRec, it indicates that we are ready to change ...
Definition: tv.h:58
This class is intended to detect the presence of needed tables.
GeneralDBOptions m_genOpt
Definition: tv_rec.h:372
bool IsRunning(void) const
Returns true if event loop has not been told to shut down.
Definition: tv_rec.h:169
Signal monitoring base class.
Definition: signalmonitor.h:32
BrowseDirection
Used to request ProgramInfo for channel browsing.
Definition: tv.h:37
uint GetFlags(void) const
Definition: tv_rec.h:243
Abstract class providing a generic interface to tuning hardware.
Definition: channelbase.h:31
PictureAdjustType
Definition: tv.h:120
uint m_channelTimeout
Definition: tv_rec.h:76
FireWireDBOptions m_fwOpt
Definition: tv_rec.h:374
QDateTime m_recordingStart
Definition: tv_rec.h:132
bool HasFlags(uint f) const
Definition: tv_rec.h:285
QString m_inputType
Definition: tv_rec.h:72
bool m_doNotAsk
Definition: tv_rec.h:136
QWaitCondition m_triggerEventLoopWait
Definition: tv_rec.h:391
bool IsErrored(void) const
Returns true is "errored" is true, false otherwise.
Definition: tv_rec.h:236
DVBDBOptions()=default
int m_connection
Definition: tv_rec.h:96
bool m_dvbEitScan
Definition: tv_rec.h:87
QString m_channel
Definition: tv_rec.h:117
QString m_model
Definition: tv_rec.h:97
bool IsRecording(void)
Returns "state == kState_RecordingRecordedOnly".
Definition: tv_rec.h:178
Implements a file/stream reader/writer.
GeneralDBOptions()=default
DVBDBOptions m_dvbOpt
Definition: tv_rec.h:373
QString toString(void) const
Definition: tv_rec.cpp:4830
bool m_canceled
Definition: tv_rec.h:134
QString m_vbiDev
Definition: tv_rec.h:70
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:656
Keeps track of recordings in a current LiveTV instance.
Definition: livetvchain.h:31
static QMap< uint, TVRec * > s_inputs
Definition: tv_rec.h:425
QDateTime m_preFailDeadline
Definition: tv_rec.h:346
Encapsulates data about MPEG stream and emits events for each table.
TuningQueue m_tuningRequests
Definition: tv_rec.h:387
TuningRequest(uint f, RecordingInfo *p)
Definition: tv_rec.h:105
bool m_ask
Definition: tv_rec.h:135
QDateTime m_startRecordingDeadline
Definition: tv_rec.h:342