MythTV  master
recorderbase.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 #ifndef RECORDERBASE_H_
3 #define RECORDERBASE_H_
4 
5 #include <cstdint>
6 
7 #include <QWaitCondition>
8 #include <QAtomicInt>
9 #include <QDateTime>
10 #include <QRunnable>
11 #include <QString>
12 #include <QMutex>
13 #include <QMap>
14 
15 #include "libmythbase/mythtimer.h"
16 #include "libmythbase/programtypes.h" // for MarkTypes, frm_pos_map_t
17 
18 #include "libmythtv/mythtvexp.h"
21 
22 extern "C"
23 {
24 #include "libavcodec/avcodec.h" // for Video/Audio codec enums
25 }
26 
27 class FireWireDBOptions;
28 class GeneralDBOptions;
29 class RecordingProfile;
30 class RecordingInfo;
31 class DVBDBOptions;
32 class RecorderBase;
33 class ChannelBase;
34 class MythMediaBuffer;
35 class TVRec;
36 
37 class FrameRate
38 {
39 public:
40  explicit FrameRate(uint n, uint d=1) : m_num(n), m_den(d) {}
41  double toDouble(void) const { return m_num / (double)m_den; }
42  bool isNonzero(void) const { return m_num != 0U; }
43  uint getNum(void) const { return m_num; }
44  uint getDen(void) const { return m_den; }
45  QString toString(void) const { return QString("%1/%2").arg(m_num).arg(m_den); }
46  bool operator==(const FrameRate other) const {
47  return m_num == other.m_num && m_den == other.m_den;
48  }
49  bool operator!=(const FrameRate other) const { return !(*this == other); }
50 private:
53 };
54 
55 enum class SCAN_t : uint8_t {
57  INTERLACED,
59  VARIABLE
60 };
61 
74 class MTV_PUBLIC RecorderBase : public QRunnable
75 {
76  friend class Transcode; // for access to SetIntOption(), SetStrOption()
77 
78  public:
79  explicit RecorderBase(TVRec *rec);
80  ~RecorderBase() override;
81 
83  void SetFrameRate(double rate)
84  {
85  m_videoFrameRate = rate;
86  m_ntscFrameRate = (29.96 <= rate && 29.98 >= rate);
87  m_frameRate = FrameRate(lround(rate * 100), 100);
88  }
89 
99  void SetRecording(const RecordingInfo *pginfo);
100 
107  void SetRingBuffer(MythMediaBuffer *Buffer);
108 
115  virtual void SetOption(const QString &name, const QString &value);
116 
121  virtual void SetOption(const QString &name, int value);
122 
127  void SetBoolOption(const QString &name, bool value)
128  { SetOption(name, static_cast<int>(value)); }
129 
136  virtual void SetVideoFilters(QString &filters) = 0;
137 
144  virtual void SetOptionsFromProfile(RecordingProfile *profile,
145  const QString &videodev,
146  const QString &audiodev,
147  const QString &vbidev) = 0;
148 
159  void SetNextRecording(const RecordingInfo *ri, MythMediaBuffer *Buffer);
160 
164  virtual void Initialize(void) = 0;
165 
170  void run(void) override = 0; // QRunnable
171 
177  virtual void Reset(void) = 0;
178 
180  virtual bool IsErrored(void) = 0;
181 
187  virtual long long GetFramesWritten(void) = 0;
188 
197  virtual int GetVideoFd(void) = 0;
198 
213  long long GetKeyframePosition(long long desired) const;
214  bool GetKeyframePositions(
215  long long start, long long end, frm_pos_map_t &map) const;
216  bool GetKeyframeDurations(
217  long long start, long long end, frm_pos_map_t &map) const;
218 
219  virtual void StopRecording(void);
220  virtual bool IsRecording(void);
221  virtual bool IsRecordingRequested(void);
222 
224  virtual RecordingQuality *GetRecordingQuality(const RecordingInfo *ri) const;
225 
226  // pausing interface
227  virtual void Pause(bool clear = true);
228  virtual void Unpause(void);
229  virtual bool IsPaused(bool holding_lock = false) const;
230  virtual bool WaitForPause(std::chrono::milliseconds timeout = 1s);
231 
234  double GetFrameRate(void) const { return m_frameRate.toDouble(); }
235 
238  virtual bool CheckForRingBufferSwitch(void);
239 
242  void SavePositionMap(bool force = false, bool finished = false);
243 
244  enum AspectRatio {
245  ASPECT_UNKNOWN = 0x00,
246  ASPECT_1_1 = 0x01,
247  ASPECT_4_3 = 0x02,
248  ASPECT_16_9 = 0x03,
249  ASPECT_2_21_1 = 0x04,
250  ASPECT_CUSTOM = 0x05,
251  };
252 
253  static RecorderBase *CreateRecorder(
254  TVRec *tvrec,
255  ChannelBase *channel,
257  const GeneralDBOptions &genOpt);
258 
259  protected:
263  void SetIntOption(RecordingProfile *profile, const QString &name);
267  void SetStrOption(RecordingProfile *profile, const QString &name);
268  virtual bool PauseAndWait(std::chrono::milliseconds timeout = 100ms);
269 
270  virtual void ResetForNewFile(void) = 0;
271  virtual void SetRecordingStatus(RecStatus::Type status,
272  const QString& file, int line);
273  virtual void ClearStatistics(void);
274  virtual void FinishRecording(void);
275  virtual void StartNewFile(void) { }
276 
279  void SetPositionMapType(MarkTypes type) { m_positionMapType = type; }
280 
283  void AspectChange(uint aspect, long long frame);
284 
287  void ResolutionChange(uint width, uint height, long long frame);
288 
291  void FrameRateChange(uint framerate, uint64_t frame);
292 
295  void VideoScanChange(SCAN_t scan, uint64_t frame);
296 
299  void VideoCodecChange(AVCodecID vCodec);
300 
303  void AudioCodecChange(AVCodecID aCodec);
304 
307  void SetDuration(std::chrono::milliseconds duration);
308 
311  void SetTotalFrames(uint64_t total_frames);
312 
313  void TryWriteProgStartMark(const frm_pos_map_t &durationDeltaCopy);
314 
315  TVRec *m_tvrec {nullptr};
316  MythMediaBuffer *m_ringBuffer {nullptr};
317  bool m_weMadeBuffer {true};
318 
319  AVContainer m_containerFormat {formatUnknown};
320  AVCodecID m_primaryVideoCodec {AV_CODEC_ID_NONE};
321  AVCodecID m_primaryAudioCodec {AV_CODEC_ID_NONE};
322  QString m_videocodec {"rtjpeg"};
323  QString m_videodevice;
324 
325  bool m_ntsc {true};
326  bool m_ntscFrameRate {true};
327  double m_videoFrameRate {29.97};
328 
329  uint m_videoAspect {0}; // AspectRatio (1 = 4:3, 2 = 16:9
330 
331  uint m_videoHeight {0};
332  uint m_videoWidth {0};
333  FrameRate m_frameRate {0};
334 
335  RecordingInfo *m_curRecording {nullptr};
336 
337  // For handling pausing + stop recording
338  mutable QMutex m_pauseLock; // also used for request_recording and recording
339  bool m_requestPause {false};
340  bool m_paused {false};
341  QWaitCondition m_pauseWait;
342  QWaitCondition m_unpauseWait;
344  bool m_requestRecording {false};
346  bool m_recording {false};
347  QWaitCondition m_recordingWait;
348 
349 
350  // For RingBuffer switching
352  MythMediaBuffer *m_nextRingBuffer {nullptr};
353  RecordingInfo *m_nextRecording {nullptr};
355 
356  // Seektable support
357  MarkTypes m_positionMapType {MARK_GOP_BYFRAME};
358  mutable QMutex m_positionMapLock;
364 
365  // ProgStart mark support
366  qint64 m_estimatedProgStartMS {0};
367  long long m_lastSavedKeyframe {0};
368  long long m_lastSavedDuration {0};
369 
370  // Statistics
371  // Note: Once we enter RecorderBase::run(), only that thread can
372  // update these values safely. These values are read in that thread
373  // without locking and updated with the lock held. Outside that
374  // thread these values are only read, and only with the lock held.
375  mutable QMutex m_statisticsLock;
376  QAtomicInt m_timeOfFirstDataIsSet; // doesn't need locking
377  QDateTime m_timeOfFirstData;
378  QAtomicInt m_timeOfLatestDataCount; // doesn't need locking
379  QAtomicInt m_timeOfLatestDataPacketInterval; // doesn't need locking
384  static constexpr std::chrono::milliseconds kTimeOfLatestDataIntervalTarget { 5s };
385 };
386 
387 #endif
388 
389 /* vim: set expandtab tabstop=4 shiftwidth=4: */
GeneralDBOptions
Definition: tv_rec.h:65
RecorderBase::m_positionMapTimer
MythTimer m_positionMapTimer
Definition: recorderbase.h:363
RecorderBase::m_timeOfLatestDataTimer
MythTimer m_timeOfLatestDataTimer
Definition: recorderbase.h:381
RecStatus::Type
Type
Definition: recordingstatus.h:15
RecorderBase::SetPositionMapType
void SetPositionMapType(MarkTypes type)
Set seektable type.
Definition: recorderbase.h:279
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:102
formatUnknown
@ formatUnknown
Definition: recordingfile.h:14
RecorderBase::m_timeOfLatestData
QDateTime m_timeOfLatestData
Definition: recorderbase.h:380
SCAN_t::VARIABLE
@ VARIABLE
FrameRate::toDouble
double toDouble(void) const
Definition: recorderbase.h:41
FrameRate::m_num
uint m_num
Definition: recorderbase.h:51
MythTimer
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:13
RecorderBase::m_statisticsLock
QMutex m_statisticsLock
Definition: recorderbase.h:375
FrameRate::getNum
uint getNum(void) const
Definition: recorderbase.h:43
RecordingInfo
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:35
mythtvexp.h
MythMediaBuffer
Definition: mythmediabuffer.h:50
build_compdb.file
file
Definition: build_compdb.py:55
force
bool force
Definition: mythcommflag.cpp:70
RecorderBase::m_timeOfLatestDataPacketInterval
QAtomicInt m_timeOfLatestDataPacketInterval
Definition: recorderbase.h:379
hardwareprofile.scan.scan
def scan(profile, smoonURL, gate)
Definition: scan.py:55
RecorderBase::m_pauseLock
QMutex m_pauseLock
Definition: recorderbase.h:338
programtypes.h
FrameRate::isNonzero
bool isNonzero(void) const
Definition: recorderbase.h:42
RecorderBase::m_recordingWait
QWaitCondition m_recordingWait
Definition: recorderbase.h:347
AVContainer
AVContainer
Definition: recordingfile.h:12
RecorderBase::m_durationMapDelta
frm_pos_map_t m_durationMapDelta
Definition: recorderbase.h:362
RecorderBase::m_ringBufferCheckTimer
MythTimer m_ringBufferCheckTimer
Definition: recorderbase.h:354
FrameRate::operator==
bool operator==(const FrameRate other) const
Definition: recorderbase.h:46
ChannelBase
Abstract class providing a generic interface to tuning hardware.
Definition: channelbase.h:31
hardwareprofile.scan.profile
profile
Definition: scan.py:97
RecorderBase::m_recordingGaps
RecordingGaps m_recordingGaps
Definition: recorderbase.h:382
recordingfile.h
FrameRate::operator!=
bool operator!=(const FrameRate other) const
Definition: recorderbase.h:49
RecorderBase::SetBoolOption
void SetBoolOption(const QString &name, bool value)
Set an specific boolean option.
Definition: recorderbase.h:127
RecorderBase::GetFrameRate
double GetFrameRate(void) const
Returns the latest frame rate.
Definition: recorderbase.h:234
FrameRate
Definition: recorderbase.h:37
clear
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
Definition: mythdb.cpp:897
MConcurrent::run
void run(const QString &name, Class *object, void(Class::*fn)())
Definition: mconcurrent.h:137
RecorderBase::m_durationMap
frm_pos_map_t m_durationMap
Definition: recorderbase.h:361
RecorderBase::m_nextRingBufferLock
QMutex m_nextRingBufferLock
Definition: recorderbase.h:351
RecordingQuality
Definition: recordingquality.h:34
uint
unsigned int uint
Definition: compat.h:81
RecorderBase::m_positionMap
frm_pos_map_t m_positionMap
Definition: recorderbase.h:359
FrameRate::m_den
uint m_den
Definition: recorderbase.h:52
frm_pos_map_t
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
Definition: programtypes.h:45
RecorderBase::m_positionMapDelta
frm_pos_map_t m_positionMapDelta
Definition: recorderbase.h:360
RecorderBase::m_videodevice
QString m_videodevice
Definition: recorderbase.h:323
FrameRate::FrameRate
FrameRate(uint n, uint d=1)
Definition: recorderbase.h:40
MTV_PUBLIC
#define MTV_PUBLIC
Definition: mythtvexp.h:15
RecorderBase::SetFrameRate
void SetFrameRate(double rate)
Sets the video frame rate.
Definition: recorderbase.h:83
RecorderBase::m_pauseWait
QWaitCondition m_pauseWait
Definition: recorderbase.h:341
recordingquality.h
Buffer
Definition: MythExternControl.h:36
SCAN_t::INTERLACED
@ INTERLACED
RecorderBase::m_timeOfFirstData
QDateTime m_timeOfFirstData
Definition: recorderbase.h:377
MARK_GOP_BYFRAME
@ MARK_GOP_BYFRAME
Definition: programtypes.h:64
FrameRate::getDen
uint getDen(void) const
Definition: recorderbase.h:44
RecorderBase::StartNewFile
virtual void StartNewFile(void)
Definition: recorderbase.h:275
RecorderBase::m_timeOfFirstDataIsSet
QAtomicInt m_timeOfFirstDataIsSet
Definition: recorderbase.h:376
RecorderBase::m_positionMapLock
QMutex m_positionMapLock
Definition: recorderbase.h:358
MarkTypes
MarkTypes
Definition: programtypes.h:47
RecorderBase
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:74
DVBDBOptions
Definition: tv_rec.h:81
RecorderBase::AspectRatio
AspectRatio
Definition: recorderbase.h:244
TVRec
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:142
FireWireDBOptions
Definition: tv_rec.h:91
SCAN_t
SCAN_t
Definition: recorderbase.h:55
SCAN_t::UNKNOWN_SCAN
@ UNKNOWN_SCAN
mythtimer.h
FrameRate::toString
QString toString(void) const
Definition: recorderbase.h:45
RecordingProfile
Definition: recordingprofile.h:41
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
RecorderBase::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: recorderbase.h:342
RecordingGaps
QList< RecordingGap > RecordingGaps
Definition: recordingquality.h:32
RecorderBase::m_timeOfLatestDataCount
QAtomicInt m_timeOfLatestDataCount
Definition: recorderbase.h:378
SCAN_t::PROGRESSIVE
@ PROGRESSIVE
Transcode
Definition: transcode.h:17