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 
49 class MTV_PUBLIC RecorderBase : public QRunnable
50 {
51  friend class Transcode; // for access to SetIntOption(), SetStrOption()
52 
53  public:
54  explicit RecorderBase(TVRec *rec);
55  ~RecorderBase() override;
56 
58  void SetFrameRate(double rate)
59  {
60  m_videoFrameRate = rate;
61  m_ntscFrameRate = (29.96 <= rate && 29.98 >= rate);
62  m_frameRate = MythAVRational(lround(rate * 100), 100);
63  }
64 
74  void SetRecording(const RecordingInfo *pginfo);
75 
82  void SetRingBuffer(MythMediaBuffer *Buffer);
83 
90  virtual void SetOption(const QString &name, const QString &value);
91 
96  virtual void SetOption(const QString &name, int value);
97 
102  void SetBoolOption(const QString &name, bool value)
103  { SetOption(name, static_cast<int>(value)); }
104 
111  virtual void SetVideoFilters(QString &filters) = 0;
112 
119  virtual void SetOptionsFromProfile(RecordingProfile *profile,
120  const QString &videodev,
121  const QString &audiodev,
122  const QString &vbidev) = 0;
123 
134  void SetNextRecording(const RecordingInfo *ri, MythMediaBuffer *Buffer);
135 
139  virtual void Initialize(void) = 0;
140 
145  void run(void) override = 0; // QRunnable
146 
152  virtual void Reset(void) = 0;
153 
155  virtual bool IsErrored(void) = 0;
156 
162  virtual long long GetFramesWritten(void) = 0;
163 
172  virtual int GetVideoFd(void) = 0;
173 
188  long long GetKeyframePosition(long long desired) const;
189  bool GetKeyframePositions(
190  long long start, long long end, frm_pos_map_t &map) const;
191  bool GetKeyframeDurations(
192  long long start, long long end, frm_pos_map_t &map) const;
193 
194  virtual void StopRecording(void);
195  virtual bool IsRecording(void);
196  virtual bool IsRecordingRequested(void);
197 
199  virtual RecordingQuality *GetRecordingQuality(const RecordingInfo *ri) const;
200 
201  // pausing interface
202  virtual void Pause(bool clear = true);
203  virtual void Unpause(void);
204  virtual bool IsPaused(bool holding_lock = false) const;
205  virtual bool WaitForPause(std::chrono::milliseconds timeout = 1s);
206 
209  double GetFrameRate(void) const { return m_frameRate.toDouble(); }
210 
213  virtual bool CheckForRingBufferSwitch(void);
214 
217  void SavePositionMap(bool force = false, bool finished = false);
218 
219  enum AspectRatio {
220  ASPECT_UNKNOWN = 0x00,
221  ASPECT_1_1 = 0x01,
222  ASPECT_4_3 = 0x02,
223  ASPECT_16_9 = 0x03,
224  ASPECT_2_21_1 = 0x04,
225  ASPECT_CUSTOM = 0x05,
226  };
227 
228  static RecorderBase *CreateRecorder(
229  TVRec *tvrec,
230  ChannelBase *channel,
232  const GeneralDBOptions &genOpt);
233 
234  protected:
238  void SetIntOption(RecordingProfile *profile, const QString &name);
242  void SetStrOption(RecordingProfile *profile, const QString &name);
243  virtual bool PauseAndWait(std::chrono::milliseconds timeout = 100ms);
244 
245  virtual void ResetForNewFile(void) = 0;
246  virtual void SetRecordingStatus(RecStatus::Type status,
247  const QString& file, int line);
248  virtual void ClearStatistics(void);
249  virtual void FinishRecording(void);
250  virtual void StartNewFile(void) { }
251 
254  void SetPositionMapType(MarkTypes type) { m_positionMapType = type; }
255 
258  void AspectChange(uint aspect, long long frame);
259 
262  void ResolutionChange(uint width, uint height, long long frame);
263 
266  void FrameRateChange(uint framerate, uint64_t frame);
267 
270  void VideoScanChange(SCAN_t scan, uint64_t frame);
271 
274  void VideoCodecChange(AVCodecID vCodec);
275 
278  void AudioCodecChange(AVCodecID aCodec);
279 
282  void SetDuration(std::chrono::milliseconds duration);
283 
286  void SetTotalFrames(uint64_t total_frames);
287 
288  void TryWriteProgStartMark(const frm_pos_map_t &durationDeltaCopy);
289 
290  TVRec *m_tvrec {nullptr};
291  MythMediaBuffer *m_ringBuffer {nullptr};
292  bool m_weMadeBuffer {true};
293 
294  AVContainer m_containerFormat {formatUnknown};
295  AVCodecID m_primaryVideoCodec {AV_CODEC_ID_NONE};
296  AVCodecID m_primaryAudioCodec {AV_CODEC_ID_NONE};
297  QString m_videocodec {"rtjpeg"};
298  QString m_videodevice;
299 
300  bool m_ntsc {true};
301  bool m_ntscFrameRate {true};
302  double m_videoFrameRate {29.97};
303 
304  uint m_videoAspect {0}; // AspectRatio (1 = 4:3, 2 = 16:9
305 
306  uint m_videoHeight {0};
307  uint m_videoWidth {0};
308  MythAVRational m_frameRate {0};
309 
310  RecordingInfo *m_curRecording {nullptr};
311 
312  // For handling pausing + stop recording
313  mutable QMutex m_pauseLock; // also used for request_recording and recording
314  bool m_requestPause {false};
315  bool m_paused {false};
316  QWaitCondition m_pauseWait;
317  QWaitCondition m_unpauseWait;
319  bool m_requestRecording {false};
321  bool m_recording {false};
322  QWaitCondition m_recordingWait;
323 
324 
325  // For RingBuffer switching
327  MythMediaBuffer *m_nextRingBuffer {nullptr};
328  RecordingInfo *m_nextRecording {nullptr};
330 
331  // Seektable support
332  MarkTypes m_positionMapType {MARK_GOP_BYFRAME};
333  mutable QMutex m_positionMapLock;
339 
340  // ProgStart mark support
341  qint64 m_estimatedProgStartMS {0};
342  long long m_lastSavedKeyframe {0};
343  long long m_lastSavedDuration {0};
344 
345  // Statistics
346  // Note: Once we enter RecorderBase::run(), only that thread can
347  // update these values safely. These values are read in that thread
348  // without locking and updated with the lock held. Outside that
349  // thread these values are only read, and only with the lock held.
350  mutable QMutex m_statisticsLock;
351  QAtomicInt m_timeOfFirstDataIsSet; // doesn't need locking
352  QDateTime m_timeOfFirstData;
353  QAtomicInt m_timeOfLatestDataCount; // doesn't need locking
354  QAtomicInt m_timeOfLatestDataPacketInterval; // doesn't need locking
359  static constexpr std::chrono::milliseconds kTimeOfLatestDataIntervalTarget { 5s };
360 };
361 
362 #endif
363 
364 /* vim: set expandtab tabstop=4 shiftwidth=4: */
GeneralDBOptions
Definition: tv_rec.h:65
RecorderBase::m_positionMapTimer
MythTimer m_positionMapTimer
Definition: recorderbase.h:338
mythavrational.h
RecorderBase::m_timeOfLatestDataTimer
MythTimer m_timeOfLatestDataTimer
Definition: recorderbase.h:356
RecStatus::Type
Type
Definition: recordingstatus.h:16
RecorderBase::SetPositionMapType
void SetPositionMapType(MarkTypes type)
Set seektable type.
Definition: recorderbase.h:254
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:101
SCAN_t
SCAN_t
Definition: scantype.h:6
RecorderBase::m_timeOfLatestData
QDateTime m_timeOfLatestData
Definition: recorderbase.h:355
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:350
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:61
RecorderBase::m_timeOfLatestDataPacketInterval
QAtomicInt m_timeOfLatestDataPacketInterval
Definition: recorderbase.h:354
hardwareprofile.scan.scan
def scan(profile, smoonURL, gate)
Definition: scan.py:54
RecorderBase::m_pauseLock
QMutex m_pauseLock
Definition: recorderbase.h:313
programtypes.h
RecorderBase::m_recordingWait
QWaitCondition m_recordingWait
Definition: recorderbase.h:322
AVContainer
AVContainer
Definition: recordingfile.h:12
RecorderBase::m_durationMapDelta
frm_pos_map_t m_durationMapDelta
Definition: recorderbase.h:337
RecorderBase::m_ringBufferCheckTimer
MythTimer m_ringBufferCheckTimer
Definition: recorderbase.h:329
ChannelBase
Abstract class providing a generic interface to tuning hardware.
Definition: channelbase.h:31
hardwareprofile.scan.profile
profile
Definition: scan.py:96
RecorderBase::m_recordingGaps
RecordingGaps m_recordingGaps
Definition: recorderbase.h:357
recordingfile.h
RecorderBase::SetBoolOption
void SetBoolOption(const QString &name, bool value)
Set an specific boolean option.
Definition: recorderbase.h:102
RecorderBase::GetFrameRate
double GetFrameRate(void) const
Returns the latest frame rate.
Definition: recorderbase.h:209
clear
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
Definition: mythdb.cpp:949
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:336
RecorderBase::m_nextRingBufferLock
QMutex m_nextRingBufferLock
Definition: recorderbase.h:326
RecordingQuality
Definition: recordingquality.h:34
RecorderBase::m_positionMap
frm_pos_map_t m_positionMap
Definition: recorderbase.h:334
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:335
RecorderBase::m_videodevice
QString m_videodevice
Definition: recorderbase.h:298
MTV_PUBLIC
#define MTV_PUBLIC
Definition: mythtvexp.h:15
RecorderBase::SetFrameRate
void SetFrameRate(double rate)
Sets the video frame rate.
Definition: recorderbase.h:58
RecorderBase::m_pauseWait
QWaitCondition m_pauseWait
Definition: recorderbase.h:316
recordingquality.h
Buffer
Definition: MythExternControl.h:36
scantype.h
RecorderBase::m_timeOfFirstData
QDateTime m_timeOfFirstData
Definition: recorderbase.h:352
RecorderBase::StartNewFile
virtual void StartNewFile(void)
Definition: recorderbase.h:250
RecorderBase::m_timeOfFirstDataIsSet
QAtomicInt m_timeOfFirstDataIsSet
Definition: recorderbase.h:351
RecorderBase::m_positionMapLock
QMutex m_positionMapLock
Definition: recorderbase.h:333
RecorderBase
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:49
DVBDBOptions
Definition: tv_rec.h:81
RecorderBase::AspectRatio
AspectRatio
Definition: recorderbase.h:219
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:317
RecordingGaps
QList< RecordingGap > RecordingGaps
Definition: recordingquality.h:32
RecorderBase::m_timeOfLatestDataCount
QAtomicInt m_timeOfLatestDataCount
Definition: recorderbase.h:353
Transcode
Definition: transcode.h:14
uint
unsigned int uint
Definition: freesurround.h:24