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 "recordingquality.h"
16 #include "programtypes.h" // for MarkTypes, frm_pos_map_t
17 #include "mythtimer.h"
18 #include "mythtvexp.h"
19 #include "recordingfile.h"
20 
21 extern "C"
22 {
23 #include "libavcodec/avcodec.h" // for Video/Audio codec enums
24 }
25 
26 class FireWireDBOptions;
27 class GeneralDBOptions;
28 class RecordingProfile;
29 class RecordingInfo;
30 class DVBDBOptions;
31 class RecorderBase;
32 class ChannelBase;
33 class MythMediaBuffer;
34 class TVRec;
35 
36 class FrameRate
37 {
38 public:
39  explicit FrameRate(uint n, uint d=1) : m_num(n), m_den(d) {}
40  double toDouble(void) const { return m_num / (double)m_den; }
41  bool isNonzero(void) const { return m_num != 0U; }
42  uint getNum(void) const { return m_num; }
43  uint getDen(void) const { return m_den; }
44  QString toString(void) const { return QString("%1/%2").arg(m_num).arg(m_den); }
45  bool operator==(const FrameRate other) const {
46  return m_num == other.m_num && m_den == other.m_den;
47  }
48  bool operator!=(const FrameRate other) const { return !(*this == other); }
49 private:
52 };
53 
54 enum class SCAN_t : uint8_t {
55  UNKNOWN_SCAN,
56  INTERLACED,
57  PROGRESSIVE,
58  VARIABLE
59 };
60 
73 class MTV_PUBLIC RecorderBase : public QRunnable
74 {
75  friend class Transcode; // for access to SetIntOption(), SetStrOption()
76 
77  public:
78  explicit RecorderBase(TVRec *rec);
79  ~RecorderBase() override;
80 
82  void SetFrameRate(double rate)
83  {
84  m_videoFrameRate = rate;
85  m_ntscFrameRate = (29.96 <= rate && 29.98 >= rate);
86  m_frameRate = FrameRate(lround(rate * 100), 100);
87  }
88 
98  void SetRecording(const RecordingInfo *pginfo);
99 
106  void SetRingBuffer(MythMediaBuffer *Buffer);
107 
114  virtual void SetOption(const QString &name, const QString &value);
115 
120  virtual void SetOption(const QString &name, int value);
121 
126  void SetBoolOption(const QString &name, bool value)
127  { SetOption(name, static_cast<int>(value)); }
128 
135  virtual void SetVideoFilters(QString &filters) = 0;
136 
144  const QString &videodev,
145  const QString &audiodev,
146  const QString &vbidev) = 0;
147 
158  void SetNextRecording(const RecordingInfo *ri, MythMediaBuffer *Buffer);
159 
163  virtual void Initialize(void) = 0;
164 
169  void run(void) override = 0; // QRunnable
170 
176  virtual void Reset(void) = 0;
177 
179  virtual bool IsErrored(void) = 0;
180 
186  virtual long long GetFramesWritten(void) = 0;
187 
196  virtual int GetVideoFd(void) = 0;
197 
212  long long GetKeyframePosition(long long desired) const;
213  bool GetKeyframePositions(
214  long long start, long long end, frm_pos_map_t &map) const;
215  bool GetKeyframeDurations(
216  long long start, long long end, frm_pos_map_t &map) const;
217 
218  virtual void StopRecording(void);
219  virtual bool IsRecording(void);
220  virtual bool IsRecordingRequested(void);
221 
223  virtual RecordingQuality *GetRecordingQuality(const RecordingInfo *ri) const;
224 
225  // pausing interface
226  virtual void Pause(bool clear = true);
227  virtual void Unpause(void);
228  virtual bool IsPaused(bool holding_lock = false) const;
229  virtual bool WaitForPause(int timeout = 1000);
230 
233  double GetFrameRate(void) const { return m_frameRate.toDouble(); }
234 
237  virtual bool CheckForRingBufferSwitch(void);
238 
241  void SavePositionMap(bool force = false, bool finished = false);
242 
243  enum AspectRatio {
244  ASPECT_UNKNOWN = 0x00,
245  ASPECT_1_1 = 0x01,
246  ASPECT_4_3 = 0x02,
247  ASPECT_16_9 = 0x03,
248  ASPECT_2_21_1 = 0x04,
249  ASPECT_CUSTOM = 0x05,
250  };
251 
252  static RecorderBase *CreateRecorder(
253  TVRec *tvrec,
256  const GeneralDBOptions &genOpt);
257 
258  protected:
262  void SetIntOption(RecordingProfile *profile, const QString &name);
266  void SetStrOption(RecordingProfile *profile, const QString &name);
267  virtual bool PauseAndWait(int timeout = 100);
268 
269  virtual void ResetForNewFile(void) = 0;
270  virtual void SetRecordingStatus(RecStatus::Type status,
271  const QString& file, int line);
272  virtual void ClearStatistics(void);
273  virtual void FinishRecording(void);
274  virtual void StartNewFile(void) { }
275 
278  void SetPositionMapType(MarkTypes type) { m_positionMapType = type; }
279 
282  void AspectChange(uint aspect, long long frame);
283 
286  void ResolutionChange(uint width, uint height, long long frame);
287 
290  void FrameRateChange(uint framerate, uint64_t frame);
291 
294  void VideoScanChange(SCAN_t scan, uint64_t frame);
295 
298  void VideoCodecChange(AVCodecID vCodec);
299 
302  void AudioCodecChange(AVCodecID aCodec);
303 
306  void SetDuration(uint64_t duration);
307 
310  void SetTotalFrames(uint64_t total_frames);
311 
312  void TryWriteProgStartMark(const frm_pos_map_t &durationDeltaCopy);
313 
314  TVRec *m_tvrec {nullptr};
315  MythMediaBuffer *m_ringBuffer {nullptr};
316  bool m_weMadeBuffer {true};
317 
318  AVContainer m_containerFormat {formatUnknown};
319  AVCodecID m_primaryVideoCodec {AV_CODEC_ID_NONE};
320  AVCodecID m_primaryAudioCodec {AV_CODEC_ID_NONE};
321  QString m_videocodec {"rtjpeg"};
322  QString m_videodevice;
323 
324  bool m_ntsc {true};
325  bool m_ntscFrameRate {true};
326  double m_videoFrameRate {29.97};
327 
328  uint m_videoAspect {0}; // AspectRatio (1 = 4:3, 2 = 16:9
329 
330  uint m_videoHeight {0};
331  uint m_videoWidth {0};
332  FrameRate m_frameRate {0};
333 
334  RecordingInfo *m_curRecording {nullptr};
335 
336  // For handling pausing + stop recording
337  mutable QMutex m_pauseLock; // also used for request_recording and recording
338  bool m_requestPause {false};
339  bool m_paused {false};
340  QWaitCondition m_pauseWait;
341  QWaitCondition m_unpauseWait;
343  bool m_requestRecording {false};
345  bool m_recording {false};
346  QWaitCondition m_recordingWait;
347 
348 
349  // For RingBuffer switching
351  MythMediaBuffer *m_nextRingBuffer {nullptr};
352  RecordingInfo *m_nextRecording {nullptr};
354 
355  // Seektable support
356  MarkTypes m_positionMapType {MARK_GOP_BYFRAME};
357  mutable QMutex m_positionMapLock;
363 
364  // ProgStart mark support
365  qint64 m_estimatedProgStartMS {0};
366  long long m_lastSavedKeyframe {0};
367  long long m_lastSavedDuration {0};
368 
369  // Statistics
370  // Note: Once we enter RecorderBase::run(), only that thread can
371  // update these values safely. These values are read in that thread
372  // without locking and updated with the lock held. Outside that
373  // thread these values are only read, and only with the lock held.
374  mutable QMutex m_statisticsLock;
375  QAtomicInt m_timeOfFirstDataIsSet; // doesn't need locking
376  QDateTime m_timeOfFirstData;
377  QAtomicInt m_timeOfLatestDataCount; // doesn't need locking
378  QAtomicInt m_timeOfLatestDataPacketInterval; // doesn't need locking
384 };
385 
386 #endif
387 
388 /* vim: set expandtab tabstop=4 shiftwidth=4: */
GeneralDBOptions
Definition: tv_rec.h:66
RecorderBase::m_positionMapTimer
MythTimer m_positionMapTimer
Definition: recorderbase.h:362
force
bool force
Definition: mythtv/programs/mythcommflag/main.cpp:74
RecorderBase::m_timeOfLatestDataTimer
MythTimer m_timeOfLatestDataTimer
Definition: recorderbase.h:380
RecStatus::Type
Type
Definition: recStatus.h:16
channel
QDomElement channel
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:501
RecorderBase::SetPositionMapType
void SetPositionMapType(MarkTypes type)
Set seektable type.
Definition: recorderbase.h:278
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
formatUnknown
@ formatUnknown
Definition: recordingfile.h:14
RecorderBase::m_timeOfLatestData
QDateTime m_timeOfLatestData
Definition: recorderbase.h:379
FrameRate::toDouble
double toDouble(void) const
Definition: recorderbase.h:40
FrameRate::m_num
uint m_num
Definition: recorderbase.h:50
MythTimer
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:14
RecorderBase::m_statisticsLock
QMutex m_statisticsLock
Definition: recorderbase.h:374
FrameRate::getNum
uint getNum(void) const
Definition: recorderbase.h:42
RecordingInfo
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:35
mythtvexp.h
RecorderBase::IsErrored
virtual bool IsErrored(void)=0
Tells us whether an unrecoverable error has been encountered.
MythMediaBuffer
Definition: mythmediabuffer.h:50
build_compdb.file
file
Definition: build_compdb.py:55
RecorderBase::kTimeOfLatestDataIntervalTarget
static const uint kTimeOfLatestDataIntervalTarget
timeOfLatest update interval target in milliseconds.
Definition: recorderbase.h:383
RecorderBase::m_timeOfLatestDataPacketInterval
QAtomicInt m_timeOfLatestDataPacketInterval
Definition: recorderbase.h:378
hardwareprofile.scan.scan
def scan(profile, smoonURL, gate)
Definition: scan.py:57
RecorderBase::m_pauseLock
QMutex m_pauseLock
Definition: recorderbase.h:337
programtypes.h
FrameRate::isNonzero
bool isNonzero(void) const
Definition: recorderbase.h:41
RecorderBase::m_recordingWait
QWaitCondition m_recordingWait
Definition: recorderbase.h:346
AVContainer
AVContainer
Definition: recordingfile.h:13
RecorderBase::m_durationMapDelta
frm_pos_map_t m_durationMapDelta
Definition: recorderbase.h:361
RecorderBase::m_ringBufferCheckTimer
MythTimer m_ringBufferCheckTimer
Definition: recorderbase.h:353
FrameRate::operator==
bool operator==(const FrameRate other) const
Definition: recorderbase.h:45
ChannelBase
Abstract class providing a generic interface to tuning hardware.
Definition: channelbase.h:32
hardwareprofile.scan.profile
profile
Definition: scan.py:99
RecorderBase::m_recordingGaps
RecordingGaps m_recordingGaps
Definition: recorderbase.h:381
RecorderBase::run
void run(void) override=0
run() starts the recording process, and does not exit until the recording is complete.
RecorderBase::Reset
virtual void Reset(void)=0
Reset the recorder to the startup state.
recordingfile.h
FrameRate::operator!=
bool operator!=(const FrameRate other) const
Definition: recorderbase.h:48
RecorderBase::SetBoolOption
void SetBoolOption(const QString &name, bool value)
Set an specific boolean option.
Definition: recorderbase.h:126
RecorderBase::GetFrameRate
double GetFrameRate(void) const
Returns the latest frame rate.
Definition: recorderbase.h:233
FrameRate
Definition: recorderbase.h:37
clear
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
Definition: mythdb.cpp:844
RecorderBase::m_durationMap
frm_pos_map_t m_durationMap
Definition: recorderbase.h:360
RecorderBase::GetVideoFd
virtual int GetVideoFd(void)=0
Returns file descriptor of recorder device.
RecorderBase::SetOptionsFromProfile
virtual void SetOptionsFromProfile(RecordingProfile *profile, const QString &videodev, const QString &audiodev, const QString &vbidev)=0
Sets basic recorder options.
RecorderBase::m_nextRingBufferLock
QMutex m_nextRingBufferLock
Definition: recorderbase.h:350
RecordingQuality
Definition: recordingquality.h:35
uint
unsigned int uint
Definition: compat.h:141
RecorderBase::m_positionMap
frm_pos_map_t m_positionMap
Definition: recorderbase.h:358
FrameRate::m_den
uint m_den
Definition: recorderbase.h:51
RecorderBase::GetFramesWritten
virtual long long GetFramesWritten(void)=0
Returns number of frames written to disk.
frm_pos_map_t
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
Definition: programtypes.h:46
RecorderBase::m_positionMapDelta
frm_pos_map_t m_positionMapDelta
Definition: recorderbase.h:359
RecorderBase::m_videodevice
QString m_videodevice
Definition: recorderbase.h:322
FrameRate::FrameRate
FrameRate(uint n, uint d=1)
Definition: recorderbase.h:39
RecorderBase::Initialize
virtual void Initialize(void)=0
This is called between SetOptionsFromProfile() and run() to initialize any devices,...
MTV_PUBLIC
#define MTV_PUBLIC
Definition: mythtvexp.h:15
RecorderBase::SetFrameRate
void SetFrameRate(double rate)
Sets the video frame rate.
Definition: recorderbase.h:82
RecorderBase::m_pauseWait
QWaitCondition m_pauseWait
Definition: recorderbase.h:340
recordingquality.h
Buffer
Definition: MythExternControl.h:37
RecorderBase::m_timeOfFirstData
QDateTime m_timeOfFirstData
Definition: recorderbase.h:376
MARK_GOP_BYFRAME
@ MARK_GOP_BYFRAME
Definition: programtypes.h:64
FrameRate::getDen
uint getDen(void) const
Definition: recorderbase.h:43
RecorderBase::StartNewFile
virtual void StartNewFile(void)
Definition: recorderbase.h:274
RecorderBase::m_timeOfFirstDataIsSet
QAtomicInt m_timeOfFirstDataIsSet
Definition: recorderbase.h:375
RecorderBase::m_positionMapLock
QMutex m_positionMapLock
Definition: recorderbase.h:357
MarkTypes
MarkTypes
Definition: programtypes.h:48
RecorderBase
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:74
DVBDBOptions
Definition: tv_rec.h:82
RecorderBase::AspectRatio
AspectRatio
Definition: recorderbase.h:243
TVRec
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:143
FireWireDBOptions
Definition: tv_rec.h:92
RecorderBase::SetVideoFilters
virtual void SetVideoFilters(QString &filters)=0
Tells recorder which filters to use.
SCAN_t
SCAN_t
Definition: recorderbase.h:54
SCAN_t::UNKNOWN_SCAN
@ UNKNOWN_SCAN
mythtimer.h
FrameRate::toString
QString toString(void) const
Definition: recorderbase.h:44
RecordingProfile
Definition: recordingprofile.h:40
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
RecorderBase::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: recorderbase.h:341
RecordingGaps
QList< RecordingGap > RecordingGaps
Definition: recordingquality.h:32
RecorderBase::m_timeOfLatestDataCount
QAtomicInt m_timeOfLatestDataCount
Definition: recorderbase.h:377
RecorderBase::ResetForNewFile
virtual void ResetForNewFile(void)=0
Transcode
Definition: transcode.h:15