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 using namespace std;
15 
16 #include <QAtomicInt>
17 #include <QString>
18 
19 #include "streamlisteners.h"
20 #include "recorderbase.h"
21 #include "H264Parser.h"
22 
23 class MPEGStreamData;
24 class TSPacket;
25 class StreamID;
26 
27 class DTVRecorder :
28  public RecorderBase,
29  public MPEGStreamListener,
31  public DVBMainStreamListener,
33  public TSPacketListener,
34  public TSPacketListenerAV,
35  public PSStreamListener
36 {
37  public:
38  explicit DTVRecorder(TVRec *rec);
39  ~DTVRecorder() override;
40 
41  void SetOption(const QString &name, const QString &value) override; // RecorderBase
42  void SetOption(const QString &name, int value) override; // RecorderBase
43  void SetOptionsFromProfile(
44  RecordingProfile *profile, const QString &videodev,
45  const QString &audiodev, const QString &vbidev) override; // RecorderBase
46 
47  bool IsErrored(void) override // RecorderBase
48  { return !m_error.isEmpty(); }
49 
50  long long GetFramesWritten(void) override // RecorderBase
51  { return m_framesWrittenCount; }
52 
53  void SetVideoFilters(QString &/*filters*/) override {;} // RecorderBase
54  void Initialize(void) override {;} // RecorderBase
55  int GetVideoFd(void) override // RecorderBase
56  { return m_streamFd; }
57 
58  virtual void SetStreamData(MPEGStreamData* data);
59  MPEGStreamData *GetStreamData(void) const { return m_streamData; }
60 
61  void Reset(void) override; // RecorderBase
62  void ClearStatistics(void) override; // RecorderBase
63  RecordingQuality *GetRecordingQuality(const RecordingInfo *r) const override; // RecorderBase
64 
65  // MPEG Stream Listener
66  void HandlePAT(const ProgramAssociationTable *_pat) override; // MPEGStreamListener
67  void HandleCAT(const ConditionalAccessTable */*cat*/) override {} // MPEGStreamListener
68  void HandlePMT(uint progNum, const ProgramMapTable *_pmt) override; // MPEGStreamListener
69  void HandleEncryptionStatus(uint /*pnum*/, bool /*encrypted*/) override { } // MPEGStreamListener
70 
71  // MPEG Single Program Stream Listener
72  void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override; // MPEGSingleProgramStreamListener
73  void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert) override; // MPEGSingleProgramStreamListener
74 
75  // ATSC Main
76  void HandleSTT(const SystemTimeTable */*stt*/) override { UpdateCAMTimeOffset(); } // ATSCMainStreamListener
77  void HandleVCT(uint /*tsid*/, const VirtualChannelTable */*vct*/) override {} // ATSCMainStreamListener
78  void HandleMGT(const MasterGuideTable */*mgt*/) override {} // ATSCMainStreamListener
79 
80  // DVBMainStreamListener
81  void HandleTDT(const TimeDateTable */*tdt*/) override { UpdateCAMTimeOffset(); } // DVBMainStreamListener
82  void HandleNIT(const NetworkInformationTable */*nit*/) override {} // DVBMainStreamListener
83  void HandleSDT(uint /*tsid*/, const ServiceDescriptionTable */*sdt*/) override {} // DVBMainStreamListener
84 
85  // TSPacketListener
86  bool ProcessTSPacket(const TSPacket &tspacket) override; // TSPacketListener
87 
88  // TSPacketListenerAV
89  bool ProcessVideoTSPacket(const TSPacket& tspacket) override; // TSPacketListenerAV
90  bool ProcessAudioTSPacket(const TSPacket& tspacket) override; // TSPacketListenerAV
91 
92  // Common audio/visual processing
93  bool ProcessAVTSPacket(const TSPacket &tspacket);
94 
95  protected:
96  virtual void InitStreamData(void);
97 
98  void FinishRecording(void) override; // RecorderBase
99  void ResetForNewFile(void) override; // RecorderBase
100 
101  void HandleKeyframe(int64_t extra);
102  void HandleTimestamps(int stream_id, int64_t pts, int64_t dts);
103  void UpdateFramesWritten(void);
104 
105  void BufferedWrite(const TSPacket &tspacket, bool insert = false);
106 
107  // MPEG TS "audio only" support
108  bool FindAudioKeyframes(const TSPacket *tspacket);
109 
110  // MPEG2 TS support
111  bool FindMPEG2Keyframes(const TSPacket* tspacket);
112 
113  // MPEG4 AVC / H.264 TS support
114  bool FindH264Keyframes(const TSPacket* tspacket);
115  void HandleH264Keyframe(void);
116 
117  // MPEG2 PS support (Hauppauge PVR-x50/PVR-500)
118  void FindPSKeyFrames(const uint8_t *buffer, uint len) override; // PSStreamListener
119 
120  // For handling other (non audio/video) packets
121  bool FindOtherKeyframes(const TSPacket *tspacket);
122 
123  inline bool CheckCC(uint pid, uint new_cnt);
124 
125  virtual QString GetSIStandard(void) const { return "mpeg"; }
126  virtual void SetCAMPMT(const ProgramMapTable */*pmt*/) {}
127  virtual void UpdateCAMTimeOffset(void) {}
128 
129  // file handle for stream
130  int m_streamFd {-1};
131 
132  QString m_recordingType {"all"};
133 
134  // used for scanning pes headers for keyframes
135  QElapsedTimer m_audioTimer;
136  uint32_t m_startCode {0xffffffff};
137  int m_firstKeyframe {-1};
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
146  int m_progressiveSequence {0};
147  int m_repeatPict {0};
148 
149  // H.264 support
150  bool m_pesSynced {false};
151  bool m_seenSps {false};
153 
155  bool m_waitForKeyframeOption {true};
156 
157  bool m_hasWrittenOtherKeyframe {false};
158 
159  // state tracking variables
161  QString m_error;
162 
163  MPEGStreamData *m_streamData {nullptr};
164 
165  // keyframe finding buffer
166  bool m_bufferPackets {false};
167  vector<unsigned char> m_payloadBuffer;
168 
169  // general recorder stuff
170  mutable QMutex m_pidLock {QMutex::Recursive};
172  ProgramAssociationTable *m_inputPat {nullptr};
174  ProgramMapTable *m_inputPmt {nullptr};
175  bool m_hasNoAV {false};
176 
177  // TS recorder stuff
178  bool m_recordMpts {false};
179  bool m_recordMptsOnly {false};
180  unsigned char m_streamId[0x1fff + 1] {0};
181  unsigned char m_pidStatus[0x1fff + 1] {0};
182  unsigned char m_continuityCounter[0x1fff + 1] {0};
183  vector<TSPacket> m_scratch;
184 
185  // Statistics
186  int m_minimumRecordingQuality {95};
187  bool m_use_pts {false}; // vs use dts
188  uint64_t m_tsCount[256] {0};
189  int64_t m_tsLast[256] {};
190  int64_t m_tsFirst[256] {};
191  QDateTime m_tsFirstDt[256];
192  mutable QAtomicInt m_packetCount {0};
193  mutable QAtomicInt m_continuityErrorCount {0};
194  unsigned long long m_framesSeenCount {0};
195  unsigned long long m_framesWrittenCount {0};
196  double m_totalDuration {0.0}; // usec
197  // Calculate m_total_duration as
198  // m_td_base + (m_td_tick_count * m_td_tick_framerate / 2)
199  double m_tdBase {0.0};
200  uint64_t m_tdTickCount {0};
201  FrameRate m_tdTickFramerate {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  // constants
212  static const unsigned char kPayloadStartSeen = 0x2;
213 };
214 
215 inline bool DTVRecorder::CheckCC(uint pid, uint new_cnt)
216 {
217  bool ok = ((((m_continuityCounter[pid] + 1) & 0xf) == new_cnt) ||
218  (m_continuityCounter[pid] == new_cnt) ||
219  (m_continuityCounter[pid] == 0xFF));
220 
221  m_continuityCounter[pid] = new_cnt & 0xf;
222 
223  return ok;
224 }
225 
226 #endif // DTVRECORDER_H
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:166
This is a specialization of RecorderBase used to handle MPEG-2, MPEG-4, MPEG-4 AVC,...
Definition: dtvrecorder.h:27
static const uint kMaxKeyFrameDistance
If the number of regular frames detected since the last detected keyframe exceeds this value,...
Definition: dtvrecorder.h:211
void SetVideoFilters(QString &) override
Tells recorder which filters to use.
Definition: dtvrecorder.h:53
This table tells the decoder on which PIDs to find A/V data.
Definition: dvbtables.h:101
virtual void UpdateCAMTimeOffset(void)
Definition: dtvrecorder.h:127
This table gives the current DVB stream time.
Definition: dvbtables.h:373
Holds information on a TV Program one might wish to record.
Definition: recordinginfo.h:34
virtual void SetCAMPMT(const ProgramMapTable *)
Definition: dtvrecorder.h:126
bool CheckCC(uint pid, uint new_cnt)
Definition: dtvrecorder.h:215
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
Definition: dtvrecorder.h:47
void HandleSDT(uint, const ServiceDescriptionTable *) override
Definition: dtvrecorder.h:83
QElapsedTimer m_audioTimer
Definition: dtvrecorder.h:135
void HandleSTT(const SystemTimeTable *) override
Definition: dtvrecorder.h:76
void HandleVCT(uint, const VirtualChannelTable *) override
Definition: dtvrecorder.h:77
void HandleNIT(const NetworkInformationTable *) override
Definition: dtvrecorder.h:82
virtual QString GetSIStandard(void) const
Definition: dtvrecorder.h:125
vector< unsigned char > m_payloadBuffer
Definition: dtvrecorder.h:167
long long GetFramesWritten(void) override
Returns number of frames written to disk.
Definition: dtvrecorder.h:50
The CAT is used to transmit additional ConditionalAccessDescriptor instances, in addition to the ones...
Definition: mpegtables.h:828
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:142
void HandleTDT(const TimeDateTable *) override
Definition: dtvrecorder.h:81
unsigned int uint
Definition: compat.h:140
void Initialize(void) override
This is called between SetOptionsFromProfile() and run() to initialize any devices,...
Definition: dtvrecorder.h:54
MPEGStreamData * GetStreamData(void) const
Definition: dtvrecorder.h:59
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:589
void HandleMGT(const MasterGuideTable *) override
Definition: dtvrecorder.h:78
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:66
This table tells the decoder on which PIDs to find other tables, and their sizes and each table's cur...
Definition: atsctables.h:74
vector< TSPacket > m_scratch
Definition: dtvrecorder.h:183
This table contains information about the channels transmitted on this multiplex.
Definition: atsctables.h:189
QString m_error
non-empty iff irrecoverable recording error detected
Definition: dtvrecorder.h:161
This table tells the decoder on which PIDs to find other tables.
Definition: dvbtables.h:21
This table contains the GPS time at the time of transmission.
Definition: atsctables.h:682
Contains listing of PMT Stream ID's for various A/V Stream types.
Definition: mpegtables.h:109
void HandleEncryptionStatus(uint, bool) override
Definition: dtvrecorder.h:69
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:666
int GetVideoFd(void) override
Returns file descriptor of recorder device.
Definition: dtvrecorder.h:55
Encapsulates data about MPEG stream and emits events for each table.
H264Parser m_h264Parser
Definition: dtvrecorder.h:152
void HandleCAT(const ConditionalAccessTable *) override
Definition: dtvrecorder.h:67