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#include "libmythbase/programtypes.h" // for MarkTypes, frm_pos_map_t
17
18#include "libmythtv/mythtvexp.h"
22#include "libmythtv/scantype.h"
23
24extern "C"
25{
26#include "libavcodec/avcodec.h" // for Video/Audio codec enums
27}
28
32class RecordingInfo;
33class DVBDBOptions;
34class RecorderBase;
35class ChannelBase;
36class MythMediaBuffer;
37class TVRec;
38
49class 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
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
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"};
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
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: */
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:50
virtual void Reset(void)=0
Reset the recorder to the startup state.
virtual void StartNewFile(void)
Definition: recorderbase.h:250
QAtomicInt m_timeOfLatestDataPacketInterval
Definition: recorderbase.h:354
virtual void ResetForNewFile(void)=0
virtual void SetVideoFilters(QString &filters)=0
Tells recorder which filters to use.
QMutex m_pauseLock
Definition: recorderbase.h:313
virtual int GetVideoFd(void)=0
Returns file descriptor of recorder device.
void SetFrameRate(double rate)
Sets the video frame rate.
Definition: recorderbase.h:58
QMutex m_nextRingBufferLock
Definition: recorderbase.h:326
frm_pos_map_t m_positionMap
Definition: recorderbase.h:334
frm_pos_map_t m_durationMapDelta
Definition: recorderbase.h:337
virtual void Initialize(void)=0
This is called between SetOptionsFromProfile() and run() to initialize any devices,...
QDateTime m_timeOfLatestData
Definition: recorderbase.h:355
QMutex m_statisticsLock
Definition: recorderbase.h:350
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:356
QDateTime m_timeOfFirstData
Definition: recorderbase.h:352
double GetFrameRate(void) const
Returns the latest frame rate.
Definition: recorderbase.h:209
MythTimer m_ringBufferCheckTimer
Definition: recorderbase.h:329
frm_pos_map_t m_positionMapDelta
Definition: recorderbase.h:335
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:336
QWaitCondition m_pauseWait
Definition: recorderbase.h:316
RecordingGaps m_recordingGaps
Definition: recorderbase.h:357
void SetBoolOption(const QString &name, bool value)
Set an specific boolean option.
Definition: recorderbase.h:102
QString m_videodevice
Definition: recorderbase.h:298
MythTimer m_positionMapTimer
Definition: recorderbase.h:338
QAtomicInt m_timeOfLatestDataCount
Definition: recorderbase.h:353
QAtomicInt m_timeOfFirstDataIsSet
Definition: recorderbase.h:351
QMutex m_positionMapLock
Definition: recorderbase.h:333
QWaitCondition m_unpauseWait
Definition: recorderbase.h:317
void SetPositionMapType(MarkTypes type)
Set seektable type.
Definition: recorderbase.h:254
QWaitCondition m_recordingWait
Definition: recorderbase.h:322
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: freesurround.h:24
bool force
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
Definition: mythdb.cpp:949
#define MTV_PUBLIC
Definition: mythtvexp.h:15
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:13
@ formatUnknown
Definition: recordingfile.h:14
QList< RecordingGap > RecordingGaps
SCAN_t
Definition: scantype.h:6