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 #include "libmythtv/scantype.h"
22 
23 extern "C"
24 {
25 #include "libavcodec/avcodec.h" // for Video/Audio codec enums
26 }
27 
28 class FireWireDBOptions;
29 class GeneralDBOptions;
30 class RecordingProfile;
31 class RecordingInfo;
32 class DVBDBOptions;
33 class RecorderBase;
34 class ChannelBase;
35 class MythMediaBuffer;
36 class TVRec;
37 
38 class FrameRate
39 {
40 public:
41  explicit FrameRate(uint n, uint d=1) : m_num(n), m_den(d) {}
42  double toDouble(void) const { return m_num / (double)m_den; }
43  bool isNonzero(void) const { return m_num != 0U; }
44  uint getNum(void) const { return m_num; }
45  uint getDen(void) const { return m_den; }
46  QString toString(void) const { return QString("%1/%2").arg(m_num).arg(m_den); }
47  bool operator==(const FrameRate other) const {
48  return m_num == other.m_num && m_den == other.m_den;
49  }
50  bool operator!=(const FrameRate other) const { return !(*this == other); }
51 private:
54 };
55 
68 class MTV_PUBLIC RecorderBase : public QRunnable
69 {
70  friend class Transcode; // for access to SetIntOption(), SetStrOption()
71 
72  public:
73  explicit RecorderBase(TVRec *rec);
74  ~RecorderBase() override;
75 
77  void SetFrameRate(double rate)
78  {
79  m_videoFrameRate = rate;
80  m_ntscFrameRate = (29.96 <= rate && 29.98 >= rate);
81  m_frameRate = FrameRate(lround(rate * 100), 100);
82  }
83 
93  void SetRecording(const RecordingInfo *pginfo);
94 
101  void SetRingBuffer(MythMediaBuffer *Buffer);
102 
109  virtual void SetOption(const QString &name, const QString &value);
110 
115  virtual void SetOption(const QString &name, int value);
116 
121  void SetBoolOption(const QString &name, bool value)
122  { SetOption(name, static_cast<int>(value)); }
123 
130  virtual void SetVideoFilters(QString &filters) = 0;
131 
138  virtual void SetOptionsFromProfile(RecordingProfile *profile,
139  const QString &videodev,
140  const QString &audiodev,
141  const QString &vbidev) = 0;
142 
153  void SetNextRecording(const RecordingInfo *ri, MythMediaBuffer *Buffer);
154 
158  virtual void Initialize(void) = 0;
159 
164  void run(void) override = 0; // QRunnable
165 
171  virtual void Reset(void) = 0;
172 
174  virtual bool IsErrored(void) = 0;
175 
181  virtual long long GetFramesWritten(void) = 0;
182 
191  virtual int GetVideoFd(void) = 0;
192 
207  long long GetKeyframePosition(long long desired) const;
208  bool GetKeyframePositions(
209  long long start, long long end, frm_pos_map_t &map) const;
210  bool GetKeyframeDurations(
211  long long start, long long end, frm_pos_map_t &map) const;
212 
213  virtual void StopRecording(void);
214  virtual bool IsRecording(void);
215  virtual bool IsRecordingRequested(void);
216 
218  virtual RecordingQuality *GetRecordingQuality(const RecordingInfo *ri) const;
219 
220  // pausing interface
221  virtual void Pause(bool clear = true);
222  virtual void Unpause(void);
223  virtual bool IsPaused(bool holding_lock = false) const;
224  virtual bool WaitForPause(std::chrono::milliseconds timeout = 1s);
225 
228  double GetFrameRate(void) const { return m_frameRate.toDouble(); }
229 
232  virtual bool CheckForRingBufferSwitch(void);
233 
236  void SavePositionMap(bool force = false, bool finished = false);
237 
238  enum AspectRatio {
239  ASPECT_UNKNOWN = 0x00,
240  ASPECT_1_1 = 0x01,
241  ASPECT_4_3 = 0x02,
242  ASPECT_16_9 = 0x03,
243  ASPECT_2_21_1 = 0x04,
244  ASPECT_CUSTOM = 0x05,
245  };
246 
247  static RecorderBase *CreateRecorder(
248  TVRec *tvrec,
249  ChannelBase *channel,
251  const GeneralDBOptions &genOpt);
252 
253  protected:
257  void SetIntOption(RecordingProfile *profile, const QString &name);
261  void SetStrOption(RecordingProfile *profile, const QString &name);
262  virtual bool PauseAndWait(std::chrono::milliseconds timeout = 100ms);
263 
264  virtual void ResetForNewFile(void) = 0;
265  virtual void SetRecordingStatus(RecStatus::Type status,
266  const QString& file, int line);
267  virtual void ClearStatistics(void);
268  virtual void FinishRecording(void);
269  virtual void StartNewFile(void) { }
270 
273  void SetPositionMapType(MarkTypes type) { m_positionMapType = type; }
274 
277  void AspectChange(uint aspect, long long frame);
278 
281  void ResolutionChange(uint width, uint height, long long frame);
282 
285  void FrameRateChange(uint framerate, uint64_t frame);
286 
289  void VideoScanChange(SCAN_t scan, uint64_t frame);
290 
293  void VideoCodecChange(AVCodecID vCodec);
294 
297  void AudioCodecChange(AVCodecID aCodec);
298 
301  void SetDuration(std::chrono::milliseconds duration);
302 
305  void SetTotalFrames(uint64_t total_frames);
306 
307  void TryWriteProgStartMark(const frm_pos_map_t &durationDeltaCopy);
308 
309  TVRec *m_tvrec {nullptr};
310  MythMediaBuffer *m_ringBuffer {nullptr};
311  bool m_weMadeBuffer {true};
312 
313  AVContainer m_containerFormat {formatUnknown};
314  AVCodecID m_primaryVideoCodec {AV_CODEC_ID_NONE};
315  AVCodecID m_primaryAudioCodec {AV_CODEC_ID_NONE};
316  QString m_videocodec {"rtjpeg"};
317  QString m_videodevice;
318 
319  bool m_ntsc {true};
320  bool m_ntscFrameRate {true};
321  double m_videoFrameRate {29.97};
322 
323  uint m_videoAspect {0}; // AspectRatio (1 = 4:3, 2 = 16:9
324 
325  uint m_videoHeight {0};
326  uint m_videoWidth {0};
327  FrameRate m_frameRate {0};
328 
329  RecordingInfo *m_curRecording {nullptr};
330 
331  // For handling pausing + stop recording
332  mutable QMutex m_pauseLock; // also used for request_recording and recording
333  bool m_requestPause {false};
334  bool m_paused {false};
335  QWaitCondition m_pauseWait;
336  QWaitCondition m_unpauseWait;
338  bool m_requestRecording {false};
340  bool m_recording {false};
341  QWaitCondition m_recordingWait;
342 
343 
344  // For RingBuffer switching
346  MythMediaBuffer *m_nextRingBuffer {nullptr};
347  RecordingInfo *m_nextRecording {nullptr};
349 
350  // Seektable support
351  MarkTypes m_positionMapType {MARK_GOP_BYFRAME};
352  mutable QMutex m_positionMapLock;
358 
359  // ProgStart mark support
360  qint64 m_estimatedProgStartMS {0};
361  long long m_lastSavedKeyframe {0};
362  long long m_lastSavedDuration {0};
363 
364  // Statistics
365  // Note: Once we enter RecorderBase::run(), only that thread can
366  // update these values safely. These values are read in that thread
367  // without locking and updated with the lock held. Outside that
368  // thread these values are only read, and only with the lock held.
369  mutable QMutex m_statisticsLock;
370  QAtomicInt m_timeOfFirstDataIsSet; // doesn't need locking
371  QDateTime m_timeOfFirstData;
372  QAtomicInt m_timeOfLatestDataCount; // doesn't need locking
373  QAtomicInt m_timeOfLatestDataPacketInterval; // doesn't need locking
378  static constexpr std::chrono::milliseconds kTimeOfLatestDataIntervalTarget { 5s };
379 };
380 
381 #endif
382 
383 /* vim: set expandtab tabstop=4 shiftwidth=4: */
GeneralDBOptions
Definition: tv_rec.h:65
RecorderBase::m_positionMapTimer
MythTimer m_positionMapTimer
Definition: recorderbase.h:357
RecorderBase::m_timeOfLatestDataTimer
MythTimer m_timeOfLatestDataTimer
Definition: recorderbase.h:375
RecStatus::Type
Type
Definition: recordingstatus.h:16
RecorderBase::SetPositionMapType
void SetPositionMapType(MarkTypes type)
Set seektable type.
Definition: recorderbase.h:273
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:102
SCAN_t
SCAN_t
Definition: scantype.h:6
RecorderBase::m_timeOfLatestData
QDateTime m_timeOfLatestData
Definition: recorderbase.h:374
FrameRate::toDouble
double toDouble(void) const
Definition: recorderbase.h:42
FrameRate::m_num
uint m_num
Definition: recorderbase.h:52
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:369
FrameRate::getNum
uint getNum(void) const
Definition: recorderbase.h:44
RecordingInfo
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:35
MarkTypes
MarkTypes
Definition: programtypes.h:47
mythtvexp.h
MythMediaBuffer
Definition: mythmediabuffer.h:59
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:373
hardwareprofile.scan.scan
def scan(profile, smoonURL, gate)
Definition: scan.py:55
RecorderBase::m_pauseLock
QMutex m_pauseLock
Definition: recorderbase.h:332
programtypes.h
FrameRate::isNonzero
bool isNonzero(void) const
Definition: recorderbase.h:43
RecorderBase::m_recordingWait
QWaitCondition m_recordingWait
Definition: recorderbase.h:341
AVContainer
AVContainer
Definition: recordingfile.h:12
RecorderBase::m_durationMapDelta
frm_pos_map_t m_durationMapDelta
Definition: recorderbase.h:356
RecorderBase::m_ringBufferCheckTimer
MythTimer m_ringBufferCheckTimer
Definition: recorderbase.h:348
FrameRate::operator==
bool operator==(const FrameRate other) const
Definition: recorderbase.h:47
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:376
recordingfile.h
FrameRate::operator!=
bool operator!=(const FrameRate other) const
Definition: recorderbase.h:50
RecorderBase::SetBoolOption
void SetBoolOption(const QString &name, bool value)
Set an specific boolean option.
Definition: recorderbase.h:121
RecorderBase::GetFrameRate
double GetFrameRate(void) const
Returns the latest frame rate.
Definition: recorderbase.h:228
FrameRate
Definition: recorderbase.h:38
clear
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
Definition: mythdb.cpp:896
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:355
RecorderBase::m_nextRingBufferLock
QMutex m_nextRingBufferLock
Definition: recorderbase.h:345
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:353
FrameRate::m_den
uint m_den
Definition: recorderbase.h:53
MARK_GOP_BYFRAME
@ MARK_GOP_BYFRAME
Definition: programtypes.h:64
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:354
RecorderBase::m_videodevice
QString m_videodevice
Definition: recorderbase.h:317
FrameRate::FrameRate
FrameRate(uint n, uint d=1)
Definition: recorderbase.h:41
MTV_PUBLIC
#define MTV_PUBLIC
Definition: mythtvexp.h:15
RecorderBase::SetFrameRate
void SetFrameRate(double rate)
Sets the video frame rate.
Definition: recorderbase.h:77
RecorderBase::m_pauseWait
QWaitCondition m_pauseWait
Definition: recorderbase.h:335
recordingquality.h
Buffer
Definition: MythExternControl.h:36
scantype.h
RecorderBase::m_timeOfFirstData
QDateTime m_timeOfFirstData
Definition: recorderbase.h:371
FrameRate::getDen
uint getDen(void) const
Definition: recorderbase.h:45
RecorderBase::StartNewFile
virtual void StartNewFile(void)
Definition: recorderbase.h:269
RecorderBase::m_timeOfFirstDataIsSet
QAtomicInt m_timeOfFirstDataIsSet
Definition: recorderbase.h:370
RecorderBase::m_positionMapLock
QMutex m_positionMapLock
Definition: recorderbase.h:352
RecorderBase
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:68
DVBDBOptions
Definition: tv_rec.h:81
RecorderBase::AspectRatio
AspectRatio
Definition: recorderbase.h:238
TVRec
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:142
FireWireDBOptions
Definition: tv_rec.h:91
formatUnknown
@ formatUnknown
Definition: recordingfile.h:14
mythtimer.h
FrameRate::toString
QString toString(void) const
Definition: recorderbase.h:46
RecordingProfile
Definition: recordingprofile.h:41
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
RecorderBase::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: recorderbase.h:336
RecordingGaps
QList< RecordingGap > RecordingGaps
Definition: recordingquality.h:32
RecorderBase::m_timeOfLatestDataCount
QAtomicInt m_timeOfLatestDataCount
Definition: recorderbase.h:372
Transcode
Definition: transcode.h:17