MythTV master
dtvrecorder.h
Go to the documentation of this file.
1// -*- Mode: c++ -*-
9#ifndef DTVRECORDER_H
10#define DTVRECORDER_H
11
12#include <vector>
13
14#include <QAtomicInt>
15#include <QString>
16
20#include "libmythtv/scantype.h"
21
22class MPEGStreamData;
23class TSPacket;
24class StreamID;
25
27 public RecorderBase,
28 public MPEGStreamListener,
32 public TSPacketListener,
33 public TSPacketListenerAV,
34 public PSStreamListener
35{
36 public:
37 explicit DTVRecorder(TVRec *rec);
38 ~DTVRecorder() override;
39
40 void SetOption(const QString &name, const QString &value) override; // RecorderBase
41 void SetOption(const QString &name, int value) override; // RecorderBase
43 RecordingProfile *profile, const QString &videodev,
44 const QString &audiodev, const QString &vbidev) override; // RecorderBase
45
46 bool IsErrored(void) override // RecorderBase
47 { return !m_error.isEmpty(); }
48
49 long long GetFramesWritten(void) override // RecorderBase
50 { return m_framesWrittenCount; }
51
52 void SetVideoFilters(QString &/*filters*/) override {;} // RecorderBase
53 void Initialize(void) override {;} // RecorderBase
54 int GetVideoFd(void) override // RecorderBase
55 { return m_streamFd; }
56
57 virtual void SetStreamData(MPEGStreamData* data);
58 MPEGStreamData *GetStreamData(void) const { return m_streamData; }
59
60 void Reset(void) override; // RecorderBase
61 void ClearStatistics(void) override; // RecorderBase
62 RecordingQuality *GetRecordingQuality(const RecordingInfo *r) const override; // RecorderBase
63
64 // MPEG Stream Listener
65 void HandlePAT(const ProgramAssociationTable *_pat) override; // MPEGStreamListener
66 void HandleCAT(const ConditionalAccessTable */*cat*/) override {} // MPEGStreamListener
67 void HandlePMT(uint progNum, const ProgramMapTable *_pmt) override; // MPEGStreamListener
68 void HandleEncryptionStatus(uint /*pnum*/, bool /*encrypted*/) override { } // MPEGStreamListener
69
70 // MPEG Single Program Stream Listener
71 void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override; // MPEGSingleProgramStreamListener
72 void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert) override; // MPEGSingleProgramStreamListener
73
74 // ATSC Main
75 void HandleSTT(const SystemTimeTable */*stt*/) override { UpdateCAMTimeOffset(); } // ATSCMainStreamListener
76 void HandleVCT(uint /*tsid*/, const VirtualChannelTable */*vct*/) override {} // ATSCMainStreamListener
77 void HandleMGT(const MasterGuideTable */*mgt*/) override {} // ATSCMainStreamListener
78
79 // DVBMainStreamListener
80 void HandleTDT(const TimeDateTable */*tdt*/) override { UpdateCAMTimeOffset(); } // DVBMainStreamListener
81 void HandleNIT(const NetworkInformationTable */*nit*/) override {} // DVBMainStreamListener
82 void HandleSDT(uint /*tsid*/, const ServiceDescriptionTable */*sdt*/) override {} // DVBMainStreamListener
83
84 // TSPacketListener
85 bool ProcessTSPacket(const TSPacket &tspacket) override; // TSPacketListener
86
87 // TSPacketListenerAV
88 bool ProcessVideoTSPacket(const TSPacket& tspacket) override; // TSPacketListenerAV
89 bool ProcessAudioTSPacket(const TSPacket& tspacket) override; // TSPacketListenerAV
90
91 // Common audio/visual processing
92 bool ProcessAVTSPacket(const TSPacket &tspacket);
93
94 protected:
95 virtual void InitStreamData(void);
96
97 void FinishRecording(void) override; // RecorderBase
98 void ResetForNewFile(void) override; // RecorderBase
99
100 void HandleKeyframe(int64_t extra);
101 void HandleTimestamps(int stream_id, int64_t pts, int64_t dts);
102 void UpdateFramesWritten(void);
103
104 void BufferedWrite(const TSPacket &tspacket, bool insert = false);
105
106 // MPEG TS "audio only" support
107 bool FindAudioKeyframes(const TSPacket *tspacket);
108
109 // MPEG2 TS support
110 bool FindMPEG2Keyframes(const TSPacket* tspacket);
111
112 // MPEG4 AVC / H.264 TS support
113 bool FindH2645Keyframes(const TSPacket* tspacket);
114 void HandleH2645Keyframe(void);
115
116 // MPEG2 PS support (Hauppauge PVR-x50/PVR-500)
117 void FindPSKeyFrames(const uint8_t *buffer, uint len) override; // PSStreamListener
118
119 // For handling other (non audio/video) packets
120 bool FindOtherKeyframes(const TSPacket *tspacket);
121
122 inline bool CheckCC(uint pid, uint new_cnt);
123
124 virtual QString GetSIStandard(void) const { return "mpeg"; }
125 virtual void SetCAMPMT(const ProgramMapTable */*pmt*/) {}
126 virtual void UpdateCAMTimeOffset(void) {}
127
128 // file handle for stream
129 int m_streamFd {-1};
130
131 QString m_recordingType {"all"};
132
133 // used for scanning pes headers for keyframes
135 QElapsedTimer m_audioTimer;
136 uint32_t m_startCode {0xffffffff};
138 unsigned long long m_lastGopSeen {0};
139 unsigned long long m_lastSeqSeen {0};
140 unsigned long long m_lastKeyframeSeen {0};
141 unsigned int m_audioBytesRemaining {0};
142 unsigned int m_videoBytesRemaining {0};
143 unsigned int m_otherBytesRemaining {0};
144
145 // MPEG2 parser information
148
149 // H.264 support
150 bool m_pesSynced {false};
151 bool m_seenSps {false};
153
156
158
159 // state tracking variables
161 QString m_error;
162
164
165 // keyframe finding buffer
166 bool m_bufferPackets {false};
167 std::vector<unsigned char> m_payloadBuffer;
168
169 // general recorder stuff
170 mutable QRecursiveMutex m_pidLock;
175 bool m_hasNoAV {false};
176
177 // TS recorder stuff
178 bool m_recordMpts {false};
179 bool m_recordMptsOnly {false};
181 std::array<uint8_t,0x1fff + 1> m_streamId {0};
182 std::array<uint8_t,0x1fff + 1> m_pidStatus {0};
183 std::array<uint8_t,0x1fff + 1> m_continuityCounter {0};
184 std::vector<TSPacket> m_scratch;
185
186 // Statistics
188 bool m_usePts {false}; // vs use dts
189 std::array<uint64_t,256> m_tsCount {0};
190 std::array<int64_t,256> m_tsLast {};
191 std::array<int64_t,256> m_tsFirst {};
192 std::array<QDateTime,256>m_tsFirstDt {};
193 mutable QAtomicInt m_packetCount {0};
194 mutable QAtomicInt m_continuityErrorCount {0};
195 unsigned long long m_framesSeenCount {0};
196 unsigned long long m_framesWrittenCount {0};
198 double m_totalDuration {0.0};
200 double m_tdBase {0.0};
207 uint64_t m_tdTickCount {0};
210
211 // Music Choice
212 // Comcast Music Choice uses 3 frames every 6 seconds and no key frames
213 bool m_musicChoice {false};
214
215 bool m_useIForKeyframe {true};
216
217 // constants
222 static const unsigned char kPayloadStartSeen = 0x2;
223};
224
225inline bool DTVRecorder::CheckCC(uint pid, uint new_cnt)
226{
227 bool ok = ((((m_continuityCounter[pid] + 1) & 0xf) == new_cnt) ||
228 (m_continuityCounter[pid] == new_cnt) ||
229 (m_continuityCounter[pid] == 0xFF));
230
231 m_continuityCounter[pid] = new_cnt & 0xf;
232
233 return ok;
234}
235
236#endif // DTVRECORDER_H
The CAT is used to transmit additional ConditionalAccessDescriptor instances, in addition to the ones...
Definition: mpegtables.h:839
This is a specialization of RecorderBase used to handle MPEG-2, MPEG-4, MPEG-4 AVC,...
Definition: dtvrecorder.h:35
bool m_seenSps
Definition: dtvrecorder.h:151
QString m_error
non-empty iff irrecoverable recording error detected
Definition: dtvrecorder.h:161
void HandleNIT(const NetworkInformationTable *) override
Definition: dtvrecorder.h:81
void FinishRecording(void) override
Flushes the ringbuffer, and if this is not a live LiveTV recording saves the position map and filesiz...
bool m_musicChoice
Definition: dtvrecorder.h:213
bool m_hasWrittenOtherKeyframe
Definition: dtvrecorder.h:157
std::array< QDateTime, 256 > m_tsFirstDt
Definition: dtvrecorder.h:192
uint32_t m_startCode
Definition: dtvrecorder.h:136
bool FindH2645Keyframes(const TSPacket *tspacket)
std::array< uint8_t, 0x1fff+1 > m_continuityCounter
Definition: dtvrecorder.h:183
unsigned int m_audioBytesRemaining
Definition: dtvrecorder.h:141
int m_minimumRecordingQuality
Definition: dtvrecorder.h:187
virtual void UpdateCAMTimeOffset(void)
Definition: dtvrecorder.h:126
bool ProcessAudioTSPacket(const TSPacket &tspacket) override
std::vector< unsigned char > m_payloadBuffer
Definition: dtvrecorder.h:167
std::array< int64_t, 256 > m_tsLast
Definition: dtvrecorder.h:190
ProgramMapTable * m_inputPmt
PMT on input side.
Definition: dtvrecorder.h:174
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
Definition: dtvrecorder.h:46
int m_repeatPict
Definition: dtvrecorder.h:147
double m_tdBase
Milliseconds from the start to m_tdTickCount = 0.
Definition: dtvrecorder.h:200
std::vector< TSPacket > m_scratch
Definition: dtvrecorder.h:184
uint64_t m_tdTickCount
Count of the number of equivalent interlaced fields that have passed since m_tdBase.
Definition: dtvrecorder.h:207
std::array< int64_t, 256 > m_tsFirst
Definition: dtvrecorder.h:191
void SetVideoFilters(QString &) override
Tells recorder which filters to use.
Definition: dtvrecorder.h:52
void HandleMGT(const MasterGuideTable *) override
Definition: dtvrecorder.h:77
RecordingQuality * GetRecordingQuality(const RecordingInfo *r) const override
Returns a report about the current recordings quality.
unsigned long long m_lastGopSeen
Definition: dtvrecorder.h:138
void HandleEncryptionStatus(uint, bool) override
Definition: dtvrecorder.h:68
unsigned long long m_lastKeyframeSeen
Definition: dtvrecorder.h:140
int GetVideoFd(void) override
Returns file descriptor of recorder device.
Definition: dtvrecorder.h:54
void ResetForNewFile(void) override
~DTVRecorder() override
Definition: dtvrecorder.cpp:67
bool m_bufferPackets
Definition: dtvrecorder.h:166
QElapsedTimer m_audioTimer
Definition: dtvrecorder.h:135
void BufferedWrite(const TSPacket &tspacket, bool insert=false)
int m_progressiveSequence
Definition: dtvrecorder.h:146
bool ProcessVideoTSPacket(const TSPacket &tspacket) override
bool ProcessTSPacket(const TSPacket &tspacket) override
bool FindOtherKeyframes(const TSPacket *tspacket)
Non-Audio/Video data.
virtual void SetCAMPMT(const ProgramMapTable *)
Definition: dtvrecorder.h:125
QString m_recordingType
Definition: dtvrecorder.h:131
unsigned int m_otherBytesRemaining
Definition: dtvrecorder.h:143
DTVRecorder(TVRec *rec)
Definition: dtvrecorder.cpp:52
void HandleH2645Keyframe(void)
This save the current frame to the position maps and handles ringbuffer switching.
MPEGStreamData * GetStreamData(void) const
Definition: dtvrecorder.h:58
unsigned long long m_framesSeenCount
Definition: dtvrecorder.h:195
MythTimer m_pesTimer
Definition: dtvrecorder.h:134
static const unsigned char kPayloadStartSeen
Definition: dtvrecorder.h:222
void HandleCAT(const ConditionalAccessTable *) override
Definition: dtvrecorder.h:66
std::array< uint8_t, 0x1fff+1 > m_streamId
Definition: dtvrecorder.h:181
std::array< uint8_t, 0x1fff+1 > m_pidStatus
Definition: dtvrecorder.h:182
virtual QString GetSIStandard(void) const
Definition: dtvrecorder.h:124
static const uint kMaxKeyFrameDistance
If the number of regular frames detected since the last detected keyframe exceeds this value,...
Definition: dtvrecorder.h:221
bool m_hasNoAV
Definition: dtvrecorder.h:175
std::array< uint64_t, 256 > m_tsCount
Definition: dtvrecorder.h:189
void HandleSTT(const SystemTimeTable *) override
Definition: dtvrecorder.h:75
void HandleTDT(const TimeDateTable *) override
Definition: dtvrecorder.h:80
ProgramAssociationTable * m_inputPat
PAT on input side.
Definition: dtvrecorder.h:172
void HandleKeyframe(int64_t extra)
This save the current frame to the position maps and handles ringbuffer switching.
H2645Parser * m_h2645Parser
Definition: dtvrecorder.h:152
void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override
void HandleVCT(uint, const VirtualChannelTable *) override
Definition: dtvrecorder.h:76
void HandlePAT(const ProgramAssociationTable *_pat) override
void Reset(void) override
Reset the recorder to the startup state.
void Initialize(void) override
This is called between SetOptionsFromProfile() and run() to initialize any devices,...
Definition: dtvrecorder.h:53
int m_firstKeyframe
Definition: dtvrecorder.h:137
MythAVRational m_tdTickFramerate
Definition: dtvrecorder.h:208
bool m_pesSynced
Definition: dtvrecorder.h:150
void HandleTimestamps(int stream_id, int64_t pts, int64_t dts)
void SetOptionsFromProfile(RecordingProfile *profile, const QString &videodev, const QString &audiodev, const QString &vbidev) override
Sets basic recorder options.
QAtomicInt m_packetCount
Definition: dtvrecorder.h:193
long long GetFramesWritten(void) override
Returns number of frames written to disk.
Definition: dtvrecorder.h:49
bool ProcessAVTSPacket(const TSPacket &tspacket)
Common code for processing either audio or video packets.
void HandlePMT(uint progNum, const ProgramMapTable *_pmt) override
bool m_waitForKeyframeOption
Wait for the a GOP/SEQ-start before sending data.
Definition: dtvrecorder.h:155
MPEGStreamData * m_streamData
Definition: dtvrecorder.h:163
void SetOption(const QString &name, const QString &value) override
Set an specific option.
Definition: dtvrecorder.cpp:92
double m_totalDuration
Total milliseconds that have passed since the start of the recording.
Definition: dtvrecorder.h:198
void FindPSKeyFrames(const uint8_t *buffer, uint len) override
QAtomicInt m_continuityErrorCount
Definition: dtvrecorder.h:194
bool m_useIForKeyframe
Definition: dtvrecorder.h:215
QRecursiveMutex m_pidLock
Definition: dtvrecorder.h:170
bool m_recordMptsOnly
Definition: dtvrecorder.h:179
unsigned int m_videoBytesRemaining
Definition: dtvrecorder.h:142
bool CheckCC(uint pid, uint new_cnt)
Definition: dtvrecorder.h:225
unsigned long long m_lastSeqSeen
Definition: dtvrecorder.h:139
void HandleSDT(uint, const ServiceDescriptionTable *) override
Definition: dtvrecorder.h:82
bool FindAudioKeyframes(const TSPacket *tspacket)
bool m_recordMpts
Definition: dtvrecorder.h:178
virtual void SetStreamData(MPEGStreamData *data)
unsigned long long m_framesWrittenCount
Definition: dtvrecorder.h:196
virtual void InitStreamData(void)
MythTimer m_recordMptsTimer
Definition: dtvrecorder.h:180
void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert) override
bool FindMPEG2Keyframes(const TSPacket *tspacket)
Locates the keyframes and saves them to the position map.
void UpdateFramesWritten(void)
SCAN_t m_scanType
Definition: dtvrecorder.h:209
void ClearStatistics(void) override
Encapsulates data about MPEG stream and emits events for each table.
This table tells the decoder on which PIDs to find other tables, and their sizes and each table's cur...
Definition: atsctables.h:83
C++ wrapper for FFmpeg libavutil AVRational.
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:14
This table tells the decoder on which PIDs to find other tables.
Definition: dvbtables.h:34
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:599
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:676
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:50
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:36
This table tells the decoder on which PIDs to find A/V data.
Definition: dvbtables.h:114
Contains listing of PMT Stream ID's for various A/V Stream types.
Definition: mpegtables.h:110
This table contains the GPS time at the time of transmission.
Definition: atsctables.h:688
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:208
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:143
This table gives the current DVB stream time.
Definition: dvbtables.h:387
This table contains information about the channels transmitted on this multiplex.
Definition: atsctables.h:197
unsigned int uint
Definition: freesurround.h:24
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
Definition: mythchrono.h:55
SCAN_t
Definition: scantype.h:6
@ UNKNOWN_SCAN