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