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"
22 #include "libmythtv/scantype.h"
23 
24 extern "C"
25 {
26 #include "libavcodec/avcodec.h" // for Video/Audio codec enums
27 }
28 
29 class FireWireDBOptions;
30 class GeneralDBOptions;
31 class RecordingProfile;
32 class RecordingInfo;
33 class DVBDBOptions;
34 class RecorderBase;
35 class ChannelBase;
36 class MythMediaBuffer;
37 class TVRec;
38 
51 class MTV_PUBLIC RecorderBase : public QRunnable
52 {
53  friend class Transcode; // for access to SetIntOption(), SetStrOption()
54 
55  public:
56  explicit RecorderBase(TVRec *rec);
57  ~RecorderBase() override;
58 
60  void SetFrameRate(double rate)
61  {
62  m_videoFrameRate = rate;
63  m_ntscFrameRate = (29.96 <= rate && 29.98 >= rate);
64  m_frameRate = MythAVRational(lround(rate * 100), 100);
65  }
66 
76  void SetRecording(const RecordingInfo *pginfo);
77 
84  void SetRingBuffer(MythMediaBuffer *Buffer);
85 
92  virtual void SetOption(const QString &name, const QString &value);
93 
98  virtual void SetOption(const QString &name, int value);
99 
104  void SetBoolOption(const QString &name, bool value)
105  { SetOption(name, static_cast<int>(value)); }
106 
113  virtual void SetVideoFilters(QString &filters) = 0;
114 
121  virtual void SetOptionsFromProfile(RecordingProfile *profile,
122  const QString &videodev,
123  const QString &audiodev,
124  const QString &vbidev) = 0;
125 
136  void SetNextRecording(const RecordingInfo *ri, MythMediaBuffer *Buffer);
137 
141  virtual void Initialize(void) = 0;
142 
147  void run(void) override = 0; // QRunnable
148 
154  virtual void Reset(void) = 0;
155 
157  virtual bool IsErrored(void) = 0;
158 
164  virtual long long GetFramesWritten(void) = 0;
165 
174  virtual int GetVideoFd(void) = 0;
175 
190  long long GetKeyframePosition(long long desired) const;
191  bool GetKeyframePositions(
192  long long start, long long end, frm_pos_map_t &map) const;
193  bool GetKeyframeDurations(
194  long long start, long long end, frm_pos_map_t &map) const;
195 
196  virtual void StopRecording(void);
197  virtual bool IsRecording(void);
198  virtual bool IsRecordingRequested(void);
199 
201  virtual RecordingQuality *GetRecordingQuality(const RecordingInfo *ri) const;
202 
203  // pausing interface
204  virtual void Pause(bool clear = true);
205  virtual void Unpause(void);
206  virtual bool IsPaused(bool holding_lock = false) const;
207  virtual bool WaitForPause(std::chrono::milliseconds timeout = 1s);
208 
211  double GetFrameRate(void) const { return m_frameRate.toDouble(); }
212 
215  virtual bool CheckForRingBufferSwitch(void);
216 
219  void SavePositionMap(bool force = false, bool finished = false);
220 
221  enum AspectRatio {
222  ASPECT_UNKNOWN = 0x00,
223  ASPECT_1_1 = 0x01,
224  ASPECT_4_3 = 0x02,
225  ASPECT_16_9 = 0x03,
226  ASPECT_2_21_1 = 0x04,
227  ASPECT_CUSTOM = 0x05,
228  };
229 
230  static RecorderBase *CreateRecorder(
231  TVRec *tvrec,
232  ChannelBase *channel,
234  const GeneralDBOptions &genOpt);
235 
236  protected:
240  void SetIntOption(RecordingProfile *profile, const QString &name);
244  void SetStrOption(RecordingProfile *profile, const QString &name);
245  virtual bool PauseAndWait(std::chrono::milliseconds timeout = 100ms);
246 
247  virtual void ResetForNewFile(void) = 0;
248  virtual void SetRecordingStatus(RecStatus::Type status,
249  const QString& file, int line);
250  virtual void ClearStatistics(void);
251  virtual void FinishRecording(void);
252  virtual void StartNewFile(void) { }
253 
256  void SetPositionMapType(MarkTypes type) { m_positionMapType = type; }
257 
260  void AspectChange(uint aspect, long long frame);
261 
264  void ResolutionChange(uint width, uint height, long long frame);
265 
268  void FrameRateChange(uint framerate, uint64_t frame);
269 
272  void VideoScanChange(SCAN_t scan, uint64_t frame);
273 
276  void VideoCodecChange(AVCodecID vCodec);
277 
280  void AudioCodecChange(AVCodecID aCodec);
281 
284  void SetDuration(std::chrono::milliseconds duration);
285 
288  void SetTotalFrames(uint64_t total_frames);
289 
290  void TryWriteProgStartMark(const frm_pos_map_t &durationDeltaCopy);
291 
292  TVRec *m_tvrec {nullptr};
293  MythMediaBuffer *m_ringBuffer {nullptr};
294  bool m_weMadeBuffer {true};
295 
296  AVContainer m_containerFormat {formatUnknown};
297  AVCodecID m_primaryVideoCodec {AV_CODEC_ID_NONE};
298  AVCodecID m_primaryAudioCodec {AV_CODEC_ID_NONE};
299  QString m_videocodec {"rtjpeg"};
300  QString m_videodevice;
301 
302  bool m_ntsc {true};
303  bool m_ntscFrameRate {true};
304  double m_videoFrameRate {29.97};
305 
306  uint m_videoAspect {0}; // AspectRatio (1 = 4:3, 2 = 16:9
307 
308  uint m_videoHeight {0};
309  uint m_videoWidth {0};
310  MythAVRational m_frameRate {0};
311 
312  RecordingInfo *m_curRecording {nullptr};
313 
314  // For handling pausing + stop recording
315  mutable QMutex m_pauseLock; // also used for request_recording and recording
316  bool m_requestPause {false};
317  bool m_paused {false};
318  QWaitCondition m_pauseWait;
319  QWaitCondition m_unpauseWait;
321  bool m_requestRecording {false};
323  bool m_recording {false};
324  QWaitCondition m_recordingWait;
325 
326 
327  // For RingBuffer switching
329  MythMediaBuffer *m_nextRingBuffer {nullptr};
330  RecordingInfo *m_nextRecording {nullptr};
332 
333  // Seektable support
334  MarkTypes m_positionMapType {MARK_GOP_BYFRAME};
335  mutable QMutex m_positionMapLock;
341 
342  // ProgStart mark support
343  qint64 m_estimatedProgStartMS {0};
344  long long m_lastSavedKeyframe {0};
345  long long m_lastSavedDuration {0};
346 
347  // Statistics
348  // Note: Once we enter RecorderBase::run(), only that thread can
349  // update these values safely. These values are read in that thread
350  // without locking and updated with the lock held. Outside that
351  // thread these values are only read, and only with the lock held.
352  mutable QMutex m_statisticsLock;
353  QAtomicInt m_timeOfFirstDataIsSet; // doesn't need locking
354  QDateTime m_timeOfFirstData;
355  QAtomicInt m_timeOfLatestDataCount; // doesn't need locking
356  QAtomicInt m_timeOfLatestDataPacketInterval; // doesn't need locking
361  static constexpr std::chrono::milliseconds kTimeOfLatestDataIntervalTarget { 5s };
362 };
363 
364 #endif
365 
366 /* vim: set expandtab tabstop=4 shiftwidth=4: */
GeneralDBOptions
Definition: tv_rec.h:65
RecorderBase::m_positionMapTimer
MythTimer m_positionMapTimer
Definition: recorderbase.h:340
mythavrational.h
RecorderBase::m_timeOfLatestDataTimer
MythTimer m_timeOfLatestDataTimer
Definition: recorderbase.h:358
RecStatus::Type
Type
Definition: recordingstatus.h:16
RecorderBase::SetPositionMapType
void SetPositionMapType(MarkTypes type)
Set seektable type.
Definition: recorderbase.h:256
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:357
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:352
RecordingInfo
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:35
MarkTypes
MarkTypes
Definition: programtypes.h:46
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:356
hardwareprofile.scan.scan
def scan(profile, smoonURL, gate)
Definition: scan.py:55
RecorderBase::m_pauseLock
QMutex m_pauseLock
Definition: recorderbase.h:315
programtypes.h
RecorderBase::m_recordingWait
QWaitCondition m_recordingWait
Definition: recorderbase.h:324
AVContainer
AVContainer
Definition: recordingfile.h:12
RecorderBase::m_durationMapDelta
frm_pos_map_t m_durationMapDelta
Definition: recorderbase.h:339
RecorderBase::m_ringBufferCheckTimer
MythTimer m_ringBufferCheckTimer
Definition: recorderbase.h:331
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:359
recordingfile.h
RecorderBase::SetBoolOption
void SetBoolOption(const QString &name, bool value)
Set an specific boolean option.
Definition: recorderbase.h:104
RecorderBase::GetFrameRate
double GetFrameRate(void) const
Returns the latest frame rate.
Definition: recorderbase.h:211
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:338
RecorderBase::m_nextRingBufferLock
QMutex m_nextRingBufferLock
Definition: recorderbase.h:328
RecordingQuality
Definition: recordingquality.h:34
RecorderBase::m_positionMap
frm_pos_map_t m_positionMap
Definition: recorderbase.h:336
MARK_GOP_BYFRAME
@ MARK_GOP_BYFRAME
Definition: programtypes.h:63
frm_pos_map_t
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
Definition: programtypes.h:44
RecorderBase::m_positionMapDelta
frm_pos_map_t m_positionMapDelta
Definition: recorderbase.h:337
RecorderBase::m_videodevice
QString m_videodevice
Definition: recorderbase.h:300
MTV_PUBLIC
#define MTV_PUBLIC
Definition: mythtvexp.h:15
RecorderBase::SetFrameRate
void SetFrameRate(double rate)
Sets the video frame rate.
Definition: recorderbase.h:60
RecorderBase::m_pauseWait
QWaitCondition m_pauseWait
Definition: recorderbase.h:318
recordingquality.h
Buffer
Definition: MythExternControl.h:36
scantype.h
RecorderBase::m_timeOfFirstData
QDateTime m_timeOfFirstData
Definition: recorderbase.h:354
RecorderBase::StartNewFile
virtual void StartNewFile(void)
Definition: recorderbase.h:252
RecorderBase::m_timeOfFirstDataIsSet
QAtomicInt m_timeOfFirstDataIsSet
Definition: recorderbase.h:353
RecorderBase::m_positionMapLock
QMutex m_positionMapLock
Definition: recorderbase.h:335
RecorderBase
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:51
DVBDBOptions
Definition: tv_rec.h:81
RecorderBase::AspectRatio
AspectRatio
Definition: recorderbase.h:221
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
MythAVRational
C++ wrapper for FFmpeg libavutil AVRational.
Definition: mythavrational.h:14
RecordingProfile
Definition: recordingprofile.h:41
RecorderBase::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: recorderbase.h:319
RecordingGaps
QList< RecordingGap > RecordingGaps
Definition: recordingquality.h:32
RecorderBase::m_timeOfLatestDataCount
QAtomicInt m_timeOfLatestDataCount
Definition: recorderbase.h:355
Transcode
Definition: transcode.h:17
uint
unsigned int uint
Definition: freesurround.h:24