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
16
17#include "libmythtv/mythtvexp.h"
19#include "libmythtv/programtypes.h" // for MarkTypes, frm_pos_map_t
23#include "libmythtv/scantype.h"
24
25extern "C"
26{
27#include "libavcodec/avcodec.h" // for Video/Audio codec enums
28}
29
33class RecordingInfo;
34class DVBDBOptions;
35class RecorderBase;
36class ChannelBase;
37class MythMediaBuffer;
38class TVRec;
39
50class MTV_PUBLIC RecorderBase : public QRunnable
51{
52 friend class Transcode; // for access to SetIntOption(), SetStrOption()
53
54 public:
55 explicit RecorderBase(TVRec *rec);
56 ~RecorderBase() override;
57
59 void SetFrameRate(double rate)
60 {
61 m_videoFrameRate = rate;
62 m_ntscFrameRate = (29.96 <= rate && 29.98 >= rate);
63 m_frameRate = MythAVRational(lround(rate * 100), 100);
64 }
65
75 void SetRecording(const RecordingInfo *pginfo);
76
83 void SetRingBuffer(MythMediaBuffer *Buffer);
84
91 virtual void SetOption(const QString &name, const QString &value);
92
97 virtual void SetOption(const QString &name, int value);
98
103 void SetBoolOption(const QString &name, bool value)
104 { SetOption(name, static_cast<int>(value)); }
105
112 virtual void SetVideoFilters(QString &filters) = 0;
113
121 const QString &videodev,
122 const QString &audiodev,
123 const QString &vbidev) = 0;
124
135 void SetNextRecording(const RecordingInfo *ri, MythMediaBuffer *Buffer);
136
140 virtual void Initialize(void) = 0;
141
146 void run(void) override = 0; // QRunnable
147
153 virtual void Reset(void) = 0;
154
156 virtual bool IsErrored(void) = 0;
157
163 virtual long long GetFramesWritten(void) = 0;
164
173 virtual int GetVideoFd(void) = 0;
174
189 long long GetKeyframePosition(long long desired) const;
190 bool GetKeyframePositions(
191 long long start, long long end, frm_pos_map_t &map) const;
192 bool GetKeyframeDurations(
193 long long start, long long end, frm_pos_map_t &map) const;
194
195 virtual void StopRecording(void);
196 virtual bool IsRecording(void);
197 virtual bool IsRecordingRequested(void);
198
200 virtual RecordingQuality *GetRecordingQuality(const RecordingInfo *ri) const;
201
202 // pausing interface
203 virtual void Pause(bool clear = true);
204 virtual void Unpause(void);
205 virtual bool IsPaused(bool holding_lock = false) const;
206 virtual bool WaitForPause(std::chrono::milliseconds timeout = 1s);
207
210 double GetFrameRate(void) const { return m_frameRate.toDouble(); }
211
214 virtual bool CheckForRingBufferSwitch(void);
215
218 void SavePositionMap(bool force = false, bool finished = false);
219
221 ASPECT_UNKNOWN = 0x00,
222 ASPECT_1_1 = 0x01,
223 ASPECT_4_3 = 0x02,
224 ASPECT_16_9 = 0x03,
225 ASPECT_2_21_1 = 0x04,
226 ASPECT_CUSTOM = 0x05,
227 };
228
229 static RecorderBase *CreateRecorder(
230 TVRec *tvrec,
231 ChannelBase *channel,
233 const GeneralDBOptions &genOpt);
234
235 protected:
239 void SetIntOption(RecordingProfile *profile, const QString &name);
243 void SetStrOption(RecordingProfile *profile, const QString &name);
244 virtual bool PauseAndWait(std::chrono::milliseconds timeout = 100ms);
245
246 virtual void ResetForNewFile(void) = 0;
247 virtual void SetRecordingStatus(RecStatus::Type status,
248 const QString& file, int line);
249 virtual void ClearStatistics(void);
250 virtual void FinishRecording(void);
251 virtual void StartNewFile(void) { }
252
255 void SetPositionMapType(MarkTypes type) { m_positionMapType = type; }
256
259 void AspectChange(uint aspect, long long frame);
260
263 void ResolutionChange(uint width, uint height, long long frame);
264
267 void FrameRateChange(uint framerate, uint64_t frame);
268
271 void VideoScanChange(SCAN_t scan, uint64_t frame);
272
275 void VideoCodecChange(AVCodecID vCodec);
276
279 void AudioCodecChange(AVCodecID aCodec);
280
283 void SetDuration(std::chrono::milliseconds duration);
284
287 void SetTotalFrames(uint64_t total_frames);
288
289 void TryWriteProgStartMark(const frm_pos_map_t &durationDeltaCopy);
290
291 TVRec *m_tvrec {nullptr};
292 MythMediaBuffer *m_ringBuffer {nullptr};
293 bool m_weMadeBuffer {true};
294
295 AVContainer m_containerFormat {formatUnknown};
296 AVCodecID m_primaryVideoCodec {AV_CODEC_ID_NONE};
297 AVCodecID m_primaryAudioCodec {AV_CODEC_ID_NONE};
298 QString m_videocodec {"rtjpeg"};
300
301 bool m_ntsc {true};
302 bool m_ntscFrameRate {true};
303 double m_videoFrameRate {29.97};
304
305 uint m_videoAspect {0}; // AspectRatio (1 = 4:3, 2 = 16:9
306
307 uint m_videoHeight {0};
308 uint m_videoWidth {0};
309 MythAVRational m_frameRate {0};
310
311 RecordingInfo *m_curRecording {nullptr};
312
313 // For handling pausing + stop recording
314 mutable QMutex m_pauseLock; // also used for request_recording and recording
315 bool m_requestPause {false};
316 bool m_paused {false};
317 QWaitCondition m_pauseWait;
318 QWaitCondition m_unpauseWait;
320 bool m_requestRecording {false};
322 bool m_recording {false};
323 QWaitCondition m_recordingWait;
324
325
326 // For RingBuffer switching
328 MythMediaBuffer *m_nextRingBuffer {nullptr};
329 RecordingInfo *m_nextRecording {nullptr};
331
332 // Seektable support
333 MarkTypes m_positionMapType {MARK_GOP_BYFRAME};
334 mutable QMutex m_positionMapLock;
340
341 // ProgStart mark support
342 qint64 m_estimatedProgStartMS {0};
343 long long m_lastSavedKeyframe {0};
344 long long m_lastSavedDuration {0};
345
346 // Statistics
347 // Note: Once we enter RecorderBase::run(), only that thread can
348 // update these values safely. These values are read in that thread
349 // without locking and updated with the lock held. Outside that
350 // thread these values are only read, and only with the lock held.
351 mutable QMutex m_statisticsLock;
352 QAtomicInt m_timeOfFirstDataIsSet; // doesn't need locking
354 QAtomicInt m_timeOfLatestDataCount; // doesn't need locking
355 QAtomicInt m_timeOfLatestDataPacketInterval; // doesn't need locking
360 static constexpr std::chrono::milliseconds kTimeOfLatestDataIntervalTarget { 5s };
361};
362
363#endif
364
365/* vim: set expandtab tabstop=4 shiftwidth=4: */
Abstract class providing a generic interface to tuning hardware.
Definition: channelbase.h:32
C++ wrapper for FFmpeg libavutil AVRational.
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:14
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:51
virtual void Reset(void)=0
Reset the recorder to the startup state.
virtual void StartNewFile(void)
Definition: recorderbase.h:251
QAtomicInt m_timeOfLatestDataPacketInterval
Definition: recorderbase.h:355
virtual void ResetForNewFile(void)=0
virtual void SetVideoFilters(QString &filters)=0
Tells recorder which filters to use.
QMutex m_pauseLock
Definition: recorderbase.h:314
virtual int GetVideoFd(void)=0
Returns file descriptor of recorder device.
void SetFrameRate(double rate)
Sets the video frame rate.
Definition: recorderbase.h:59
QMutex m_nextRingBufferLock
Definition: recorderbase.h:327
frm_pos_map_t m_positionMap
Definition: recorderbase.h:335
frm_pos_map_t m_durationMapDelta
Definition: recorderbase.h:338
virtual void Initialize(void)=0
This is called between SetOptionsFromProfile() and run() to initialize any devices,...
QDateTime m_timeOfLatestData
Definition: recorderbase.h:356
QMutex m_statisticsLock
Definition: recorderbase.h:351
void run(void) override=0
run() starts the recording process, and does not exit until the recording is complete.
MythTimer m_timeOfLatestDataTimer
Definition: recorderbase.h:357
QDateTime m_timeOfFirstData
Definition: recorderbase.h:353
double GetFrameRate(void) const
Returns the latest frame rate.
Definition: recorderbase.h:210
MythTimer m_ringBufferCheckTimer
Definition: recorderbase.h:330
frm_pos_map_t m_positionMapDelta
Definition: recorderbase.h:336
virtual void SetOptionsFromProfile(RecordingProfile *profile, const QString &videodev, const QString &audiodev, const QString &vbidev)=0
Sets basic recorder options.
virtual long long GetFramesWritten(void)=0
Returns number of frames written to disk.
frm_pos_map_t m_durationMap
Definition: recorderbase.h:337
QWaitCondition m_pauseWait
Definition: recorderbase.h:317
RecordingGaps m_recordingGaps
Definition: recorderbase.h:358
void SetBoolOption(const QString &name, bool value)
Set an specific boolean option.
Definition: recorderbase.h:103
QString m_videodevice
Definition: recorderbase.h:299
MythTimer m_positionMapTimer
Definition: recorderbase.h:339
QAtomicInt m_timeOfLatestDataCount
Definition: recorderbase.h:354
QAtomicInt m_timeOfFirstDataIsSet
Definition: recorderbase.h:352
QMutex m_positionMapLock
Definition: recorderbase.h:334
QWaitCondition m_unpauseWait
Definition: recorderbase.h:318
void SetPositionMapType(MarkTypes type)
Set seektable type.
Definition: recorderbase.h:255
QWaitCondition m_recordingWait
Definition: recorderbase.h:323
virtual bool IsErrored(void)=0
Tells us whether an unrecoverable error has been encountered.
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:36
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:143
unsigned int uint
Definition: compat.h:68
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
Definition: mythdb.cpp:949
#define MTV_PUBLIC
Definition: mythtvexp.h:11
def scan(profile, smoonURL, gate)
Definition: scan.py:54
MarkTypes
Definition: programtypes.h:46
@ MARK_GOP_BYFRAME
Definition: programtypes.h:63
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
Definition: programtypes.h:44
AVContainer
Definition: recordingfile.h:12
@ formatUnknown
Definition: recordingfile.h:13
QList< RecordingGap > RecordingGaps
SCAN_t
Definition: scantype.h:6