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 QTime;
26 class StreamID;
27 
28 class DTVRecorder :
29  public RecorderBase,
30  public MPEGStreamListener,
32  public DVBMainStreamListener,
34  public TSPacketListener,
35  public TSPacketListenerAV,
36  public PSStreamListener
37 {
38  public:
39  explicit DTVRecorder(TVRec *rec);
40  virtual ~DTVRecorder();
41 
42  void SetOption(const QString &name, const QString &value) override; // RecorderBase
43  void SetOption(const QString &name, int value) override; // RecorderBase
44  void SetOptionsFromProfile(
45  RecordingProfile *profile, const QString &videodev,
46  const QString&, const QString&) override; // RecorderBase
47 
48  bool IsErrored(void) override // RecorderBase
49  { return !m_error.isEmpty(); }
50 
51  long long GetFramesWritten(void) override // RecorderBase
52  { return m_frames_written_count; }
53 
54  void SetVideoFilters(QString &/*filters*/) override {;} // RecorderBase
55  void Initialize(void) override {;} // RecorderBase
56  int GetVideoFd(void) override // RecorderBase
57  { return m_stream_fd; }
58 
59  virtual void SetStreamData(MPEGStreamData* data);
60  MPEGStreamData *GetStreamData(void) const { return m_stream_data; }
61 
62  void Reset(void) override; // RecorderBase
63  void ClearStatistics(void) override; // RecorderBase
64  RecordingQuality *GetRecordingQuality(const RecordingInfo*) const override; // RecorderBase
65 
66  // MPEG Stream Listener
67  void HandlePAT(const ProgramAssociationTable*) override; // MPEGStreamListener
68  void HandleCAT(const ConditionalAccessTable*) override {} // MPEGStreamListener
69  void HandlePMT(uint progNum, const ProgramMapTable*) override; // MPEGStreamListener
70  void HandleEncryptionStatus(uint /*pnum*/, bool /*encrypted*/) override { } // MPEGStreamListener
71 
72  // MPEG Single Program Stream Listener
73  void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override; // MPEGSingleProgramStreamListener
74  void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert) override; // MPEGSingleProgramStreamListener
75 
76  // ATSC Main
77  void HandleSTT(const SystemTimeTable*) override { UpdateCAMTimeOffset(); } // ATSCMainStreamListener
78  void HandleVCT(uint /*tsid*/, const VirtualChannelTable*) override {} // ATSCMainStreamListener
79  void HandleMGT(const MasterGuideTable*) override {} // ATSCMainStreamListener
80 
81  // DVBMainStreamListener
82  void HandleTDT(const TimeDateTable*) override { UpdateCAMTimeOffset(); } // DVBMainStreamListener
83  void HandleNIT(const NetworkInformationTable*) override {} // DVBMainStreamListener
84  void HandleSDT(uint /*tsid*/, const ServiceDescriptionTable*) override {} // DVBMainStreamListener
85 
86  // TSPacketListener
87  bool ProcessTSPacket(const TSPacket &tspacket) override; // TSPacketListener
88 
89  // TSPacketListenerAV
90  bool ProcessVideoTSPacket(const TSPacket& tspacket) override; // TSPacketListenerAV
91  bool ProcessAudioTSPacket(const TSPacket& tspacket) override; // TSPacketListenerAV
92 
93  // Common audio/visual processing
94  bool ProcessAVTSPacket(const TSPacket &tspacket);
95 
96  protected:
97  virtual void InitStreamData(void);
98 
99  void FinishRecording(void) override; // RecorderBase
100  void ResetForNewFile(void) override; // RecorderBase
101 
102  void HandleKeyframe(int64_t extra);
103  void HandleTimestamps(int stream_id, int64_t pts, int64_t dts);
104  void UpdateFramesWritten(void);
105 
106  void BufferedWrite(const TSPacket &tspacket, bool insert = false);
107 
108  // MPEG TS "audio only" support
109  bool FindAudioKeyframes(const TSPacket *tspacket);
110 
111  // MPEG2 TS support
112  bool FindMPEG2Keyframes(const TSPacket* tspacket);
113 
114  // MPEG4 AVC / H.264 TS support
115  bool FindH264Keyframes(const TSPacket* tspacket);
116  void HandleH264Keyframe(void);
117 
118  // MPEG2 PS support (Hauppauge PVR-x50/PVR-500)
119  void FindPSKeyFrames(const uint8_t *buffer, uint len) override; // PSStreamListener
120 
121  // For handling other (non audio/video) packets
122  bool FindOtherKeyframes(const TSPacket *tspacket);
123 
124  inline bool CheckCC(uint pid, uint cc);
125 
126  virtual QString GetSIStandard(void) const { return "mpeg"; }
127  virtual void SetCAMPMT(const ProgramMapTable*) {}
128  virtual void UpdateCAMTimeOffset(void) {}
129 
130  // file handle for stream
131  int m_stream_fd {-1};
132 
133  QString m_recording_type {"all"};
134 
135  // used for scanning pes headers for keyframes
137  uint32_t m_start_code {0xffffffff};
138  int m_first_keyframe {-1};
139  unsigned long long m_last_gop_seen {0};
140  unsigned long long m_last_seq_seen {0};
141  unsigned long long m_last_keyframe_seen {0};
142  unsigned int m_audio_bytes_remaining {0};
143  unsigned int m_video_bytes_remaining {0};
144  unsigned int m_other_bytes_remaining {0};
145 
146  // MPEG2 parser information
147  int m_progressive_sequence {0};
148  int m_repeat_pict {0};
149 
150  // H.264 support
151  bool m_pes_synced {false};
152  bool m_seen_sps {false};
154 
156  bool m_wait_for_keyframe_option {true};
157 
158  bool m_has_written_other_keyframe {false};
159 
160  // state tracking variables
162  QString m_error;
163 
164  MPEGStreamData *m_stream_data {nullptr};
165 
166  // keyframe finding buffer
167  bool m_buffer_packets {false};
168  vector<unsigned char> m_payload_buffer;
169 
170  // general recorder stuff
171  mutable QMutex m_pid_lock {QMutex::Recursive};
173  ProgramAssociationTable *m_input_pat {nullptr};
175  ProgramMapTable *m_input_pmt {nullptr};
176  bool m_has_no_av {false};
177 
178  // TS recorder stuff
179  bool m_record_mpts {false};
180  bool m_record_mpts_only {false};
181  unsigned char m_stream_id[0x1fff + 1];
182  unsigned char m_pid_status[0x1fff + 1];
183  unsigned char m_continuity_counter[0x1fff + 1];
184  vector<TSPacket> m_scratch;
185 
186  // Statistics
188  bool m_use_pts {false}; // vs use dts
189  uint64_t m_ts_count[256];
190  int64_t m_ts_last[256];
191  int64_t m_ts_first[256];
192  QDateTime m_ts_first_dt[256];
193  mutable QAtomicInt m_packet_count {0};
194  mutable QAtomicInt m_continuity_error_count {0};
195  unsigned long long m_frames_seen_count {0};
196  unsigned long long m_frames_written_count {0};
197  double m_total_duration {0.0}; // usec
198  // Calculate m_total_duration as
199  // m_td_base + (m_td_tick_count * m_td_tick_framerate / 2)
200  double m_td_base {0.0};
201  uint64_t m_td_tick_count {0};
202  FrameRate m_td_tick_framerate {0};
203 
204  // Music Choice
205  // Comcast Music Choice uses 3 frames every 6 seconds and no key frames
206  bool m_music_choice {false};
207 
208  // constants
213  static const unsigned char kPayloadStartSeen = 0x2;
214 };
215 
216 inline bool DTVRecorder::CheckCC(uint pid, uint new_cnt)
217 {
218  bool ok = ((((m_continuity_counter[pid] + 1) & 0xf) == new_cnt) ||
219  (m_continuity_counter[pid] == new_cnt) ||
220  (m_continuity_counter[pid] == 0xFF));
221 
222  m_continuity_counter[pid] = new_cnt & 0xf;
223 
224  return ok;
225 }
226 
227 #endif // DTVRECORDER_H
H264Parser m_h264_parser
Definition: dtvrecorder.h:153
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:166
Definition: cc.h:13
This is a specialization of RecorderBase used to handle MPEG-2, MPEG-4, MPEG-4 AVC,...
Definition: dtvrecorder.h:28
static const uint kMaxKeyFrameDistance
If the number of regular frames detected since the last detected keyframe exceeds this value,...
Definition: dtvrecorder.h:212
void SetVideoFilters(QString &) override
Tells recorder which filters to use.
Definition: dtvrecorder.h:54
This table tells the decoder on which PIDs to find A/V data.
Definition: dvbtables.h:101
virtual void UpdateCAMTimeOffset(void)
Definition: dtvrecorder.h:128
int m_minimum_recording_quality
Definition: dtvrecorder.h:187
bool CheckCC(uint pid, uint cc)
Definition: dtvrecorder.h:216
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:127
unsigned int uint
Definition: compat.h:140
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
Definition: dtvrecorder.h:48
void HandleSDT(uint, const ServiceDescriptionTable *) override
Definition: dtvrecorder.h:84
void HandleSTT(const SystemTimeTable *) override
Definition: dtvrecorder.h:77
void HandleVCT(uint, const VirtualChannelTable *) override
Definition: dtvrecorder.h:78
void HandleNIT(const NetworkInformationTable *) override
Definition: dtvrecorder.h:83
virtual QString GetSIStandard(void) const
Definition: dtvrecorder.h:126
long long GetFramesWritten(void) override
Returns number of frames written to disk.
Definition: dtvrecorder.h:51
The CAT is used to transmit additional ConditionalAccessDescriptor instances, in addition to the ones...
Definition: mpegtables.h:818
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:150
void HandleTDT(const TimeDateTable *) override
Definition: dtvrecorder.h:82
void Initialize(void) override
This is called between SetOptionsFromProfile() and run() to initialize any devices,...
Definition: dtvrecorder.h:55
QTime m_audio_timer
Definition: dtvrecorder.h:136
MPEGStreamData * GetStreamData(void) const
Definition: dtvrecorder.h:60
const char * name
Definition: ParseText.cpp:328
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:579
void HandleMGT(const MasterGuideTable *) override
Definition: dtvrecorder.h:79
This is the abstract base class for supporting recorder hardware.
Definition: recorderbase.h:66
vector< unsigned char > m_payload_buffer
Definition: dtvrecorder.h:168
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:184
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:162
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:683
Contains listing of PMT Stream ID's for various A/V Stream types.
Definition: mpegtables.h:106
void HandleEncryptionStatus(uint, bool) override
Definition: dtvrecorder.h:70
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:656
int GetVideoFd(void) override
Returns file descriptor of recorder device.
Definition: dtvrecorder.h:56
Encapsulates data about MPEG stream and emits events for each table.
void HandleCAT(const ConditionalAccessTable *) override
Definition: dtvrecorder.h:68