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 RingBuffer;
34 class TVRec;
35 
36 class FrameRate
37 {
38 public:
39  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; }
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) {
46  return m_num == other.m_num && m_den == other.m_den;
47  }
48  bool operator!=(const FrameRate &other) { return !(*this == other); }
49 private:
52 };
53 
66 class MTV_PUBLIC RecorderBase : public QRunnable
67 {
68  friend class Transcode; // for access to SetIntOption(), SetStrOption()
69 
70  public:
71  explicit RecorderBase(TVRec *rec);
72  virtual ~RecorderBase();
73 
75  void SetFrameRate(double rate)
76  {
77  m_video_frame_rate = rate;
78  m_ntsc_framerate = (29.96 <= rate && 29.98 >= rate);
79  m_frameRate = FrameRate((rate * 100) + 0.5, 100);
80  }
81 
91  void SetRecording(const RecordingInfo *pginfo);
92 
99  void SetRingBuffer(RingBuffer *rbuf);
100 
107  virtual void SetOption(const QString &name, const QString &value);
108 
113  virtual void SetOption(const QString &name, int value);
114 
119  void SetBoolOption(const QString &name, bool value)
120  { SetOption(name, static_cast<int>(value)); }
121 
128  virtual void SetVideoFilters(QString &filters) = 0;
129 
136  virtual void SetOptionsFromProfile(RecordingProfile *profile,
137  const QString &videodev,
138  const QString &audiodev,
139  const QString &vbidev) = 0;
140 
151  void SetNextRecording(const RecordingInfo*, RingBuffer*);
152 
156  virtual void Initialize(void) = 0;
157 
162  void run(void) override = 0; // QRunnable
163 
169  virtual void Reset(void) = 0;
170 
172  virtual bool IsErrored(void) = 0;
173 
179  virtual long long GetFramesWritten(void) = 0;
180 
189  virtual int GetVideoFd(void) = 0;
190 
205  long long GetKeyframePosition(long long desired) const;
206  bool GetKeyframePositions(
207  long long start, long long end, frm_pos_map_t&) const;
208  bool GetKeyframeDurations(
209  long long start, long long end, frm_pos_map_t&) const;
210 
211  virtual void StopRecording(void);
212  virtual bool IsRecording(void);
213  virtual bool IsRecordingRequested(void);
214 
216  virtual RecordingQuality *GetRecordingQuality(const RecordingInfo*) const;
217 
218  // pausing interface
219  virtual void Pause(bool clear = true);
220  virtual void Unpause(void);
221  virtual bool IsPaused(bool holding_lock = false) const;
222  virtual bool WaitForPause(int timeout = 1000);
223 
226  double GetFrameRate(void) const { return m_frameRate.toDouble(); }
227 
230  virtual bool CheckForRingBufferSwitch(void);
231 
234  void SavePositionMap(bool force = false, bool finished = false);
235 
236  enum AspectRatio {
237  ASPECT_UNKNOWN = 0x00,
238  ASPECT_1_1 = 0x01,
239  ASPECT_4_3 = 0x02,
240  ASPECT_16_9 = 0x03,
241  ASPECT_2_21_1 = 0x04,
242  ASPECT_CUSTOM = 0x05,
243  };
244 
245  static RecorderBase *CreateRecorder(
246  TVRec *tvrec,
247  ChannelBase *channel,
248  const RecordingProfile &profile,
249  const GeneralDBOptions &genOpt);
250 
251  protected:
255  void SetIntOption(RecordingProfile *profile, const QString &name);
259  void SetStrOption(RecordingProfile *profile, const QString &name);
260  virtual bool PauseAndWait(int timeout = 100);
261 
262  virtual void ResetForNewFile(void) = 0;
263  virtual void SetRecordingStatus(RecStatus::Type status,
264  const QString& file, int line);
265  virtual void ClearStatistics(void);
266  virtual void FinishRecording(void);
267  virtual void StartNewFile(void) { }
268 
271  void SetPositionMapType(MarkTypes type) { m_positionMapType = type; }
272 
275  void AspectChange(uint aspect, long long frame);
276 
279  void ResolutionChange(uint width, uint height, long long frame);
280 
283  void FrameRateChange(uint framerate, long long frame);
284 
287  void VideoCodecChange(AVCodecID vCodec);
288 
291  void AudioCodecChange(AVCodecID aCodec);
292 
295  void SetDuration(uint64_t duration);
296 
299  void SetTotalFrames(uint64_t total_frames);
300 
301  void TryWriteProgStartMark(const frm_pos_map_t &durationDeltaCopy);
302 
303  TVRec *m_tvrec {nullptr};
304  RingBuffer *m_ringBuffer {nullptr};
305  bool m_weMadeBuffer {true};
306 
307  AVContainer m_containerFormat {formatUnknown};
308  AVCodecID m_primaryVideoCodec {AV_CODEC_ID_NONE};
309  AVCodecID m_primaryAudioCodec {AV_CODEC_ID_NONE};
310  QString m_videocodec {"rtjpeg"};
311  QString m_videodevice;
312 
313  bool m_ntsc {true};
314  bool m_ntsc_framerate {true};
315  double m_video_frame_rate {29.97};
316 
317  uint m_videoAspect {0}; // AspectRatio (1 = 4:3, 2 = 16:9
318 
319  uint m_videoHeight {0};
320  uint m_videoWidth {0};
321  FrameRate m_frameRate {0};
322 
323  RecordingInfo *m_curRecording {nullptr};
324 
325  // For handling pausing + stop recording
326  mutable QMutex m_pauseLock; // also used for request_recording and recording
327  bool m_request_pause {false};
328  bool m_paused {false};
329  QWaitCondition m_pauseWait;
330  QWaitCondition m_unpauseWait;
332  bool m_request_recording {false};
334  bool m_recording {false};
335  QWaitCondition m_recordingWait;
336 
337 
338  // For RingBuffer switching
340  RingBuffer *m_nextRingBuffer {nullptr};
341  RecordingInfo *m_nextRecording {nullptr};
343 
344  // Seektable support
345  MarkTypes m_positionMapType {MARK_GOP_BYFRAME};
346  mutable QMutex m_positionMapLock;
352 
353  // ProgStart mark support
354  qint64 m_estimatedProgStartMS {0};
355  long long m_lastSavedKeyframe {0};
356  long long m_lastSavedDuration {0};
357 
358  // Statistics
359  // Note: Once we enter RecorderBase::run(), only that thread can
360  // update these values safely. These values are read in that thread
361  // without locking and updated with the lock held. Outside that
362  // thread these values are only read, and only with the lock held.
363  mutable QMutex m_statisticsLock;
364  QAtomicInt m_timeOfFirstDataIsSet; // doesn't need locking
365  QDateTime m_timeOfFirstData;
366  QAtomicInt m_timeOfLatestDataCount; // doesn't need locking
367  QAtomicInt m_timeOfLatestDataPacketInterval; // doesn't need locking
373 };
374 
375 #endif
376 
377 /* vim: set expandtab tabstop=4 shiftwidth=4: */
frm_pos_map_t m_durationMap
Definition: recorderbase.h:349
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:13
QMutex m_nextRingBufferLock
Definition: recorderbase.h:339
QAtomicInt m_timeOfLatestDataPacketInterval
Definition: recorderbase.h:367
frm_pos_map_t m_positionMap
Definition: recorderbase.h:347
QString toString(void) const
Definition: recorderbase.h:44
QMutex m_pauseLock
Definition: recorderbase.h:326
virtual void StartNewFile(void)
Definition: recorderbase.h:267
enum AVContainerFormats AVContainer
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:34
bool operator!=(const FrameRate &other)
Definition: recorderbase.h:48
uint getNum(void) const
Definition: recorderbase.h:42
unsigned int uint
Definition: compat.h:140
QDateTime m_timeOfFirstData
Definition: recorderbase.h:365
QMutex m_statisticsLock
Definition: recorderbase.h:363
QWaitCondition m_unpauseWait
Definition: recorderbase.h:330
MarkTypes
Definition: programtypes.h:48
double toDouble(void) const
Definition: recorderbase.h:40
uint m_num
Definition: recorderbase.h:50
bool operator==(const FrameRate &other)
Definition: recorderbase.h:45
void SetFrameRate(double rate)
Sets the video frame rate.
Definition: recorderbase.h:75
#define MTV_PUBLIC
Definition: mythtvexp.h:15
QWaitCondition m_pauseWait
Definition: recorderbase.h:329
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:150
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
Definition: mythdb.cpp:830
QAtomicInt m_timeOfLatestDataCount
Definition: recorderbase.h:366
void SetPositionMapType(MarkTypes type)
Set seektable type.
Definition: recorderbase.h:271
static const uint16_t * d
QDateTime m_timeOfLatestData
Definition: recorderbase.h:368
FrameRate(uint n, uint d=1)
Definition: recorderbase.h:39
MythTimer m_ringBufferCheckTimer
Definition: recorderbase.h:342
QWaitCondition m_recordingWait
Definition: recorderbase.h:335
const char * name
Definition: ParseText.cpp:328
MythTimer m_timeOfLatestDataTimer
Definition: recorderbase.h:369
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:66
bool isNonzero(void) const
Definition: recorderbase.h:41
RecordingGaps m_recordingGaps
Definition: recorderbase.h:370
Abstract class providing a generic interface to tuning hardware.
Definition: channelbase.h:31
uint m_den
Definition: recorderbase.h:51
static const uint kTimeOfLatestDataIntervalTarget
timeOfLatest update interval target in milliseconds.
Definition: recorderbase.h:372
QList< RecordingGap > RecordingGaps
frm_pos_map_t m_positionMapDelta
Definition: recorderbase.h:348
MythTimer m_positionMapTimer
Definition: recorderbase.h:351
frm_pos_map_t m_durationMapDelta
Definition: recorderbase.h:350
QString m_videodevice
Definition: recorderbase.h:311
Implements a file/stream reader/writer.
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
Definition: programtypes.h:46
void SetBoolOption(const QString &name, bool value)
Set an specific boolean option.
Definition: recorderbase.h:119
QAtomicInt m_timeOfFirstDataIsSet
Definition: recorderbase.h:364
QMutex m_positionMapLock
Definition: recorderbase.h:346
double GetFrameRate(void) const
Returns the latest frame rate.
Definition: recorderbase.h:226
uint getDen(void) const
Definition: recorderbase.h:43