MythTV  master
tspacket.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // Copyright (c) 2003-2004,2010 Daniel Thor Kristjansson
3 #ifndef _TS_PACKET_H_
4 #define _TS_PACKET_H_
5 
6 #include <chrono>
7 #include <cstdlib>
8 #include "mythcontext.h"
9 #include "mythtvexp.h"
10 
11 // n.b. these PID relationships are only a recommendation from ATSC,
12 // but seem to be universal
13 #define VIDEO_PID(bp) ((bp)+1)
14 #define AUDIO_PID(bp) ((bp)+4)
15 #define SYNC_BYTE 0x0047
16 
25 {
26  public:
27  using Clock = std::chrono::steady_clock;
28  using TimePoint = std::chrono::time_point<Clock, std::chrono::microseconds>;
29 
30  TSHeader(void)
31  {
32  _tsdata[0] = SYNC_BYTE;
33  /*
34  no need to init rest of header, this is only a part of a larger
35  packets which initialize the rest of the data differently.
36  */
37  }
38  explicit TSHeader(int cc)
39  {
40  _tsdata[0] = SYNC_BYTE;
41  SetContinuityCounter(cc);
42  /*
43  no need to init rest of header, this is only a part of a larger
44  packets which initialize the rest of the data differently.
45  */
46  }
47  void InitHeader(const unsigned char* header) {
48  if (header)
49  {
50  _tsdata[0]=header[0];
51  _tsdata[1]=header[1];
52  _tsdata[2]=header[2];
53  _tsdata[3]=header[3];
54  }
55  }
56 
57  // Decode the link header (bytes 0-4):
58  // gets
59 
60  //0.0 8 bits SYNC_BYTE
61  bool HasSync(void) const { return SYNC_BYTE == _tsdata[0]; }
62  //1.0 1 bit transport_packet_error (if set discard immediately:
63  // modem error)
64  bool TransportError(void) const { return bool(_tsdata[1]&0x80); }
65  //1.1 1 bit payload_unit_start_indicator
66  // (if set this packet starts a section, and has pointerField)
67  bool PayloadStart(void) const { return bool(_tsdata[1]&0x40); }
68  //1.2 1 bit transport_priority (ignore)
69  bool Priority(void) const { return bool(_tsdata[1]&0x20); }
70  //1.3 13 bit PID (packet ID, which transport stream)
71  inline unsigned int PID(void) const {
72  return ((_tsdata[1] << 8) + _tsdata[2]) & 0x1fff;
73  }
74  //3.0 2 bit transport_scrambling_control (00,01 OK; 10,11 scrambled)
75  unsigned int ScramblingControl(void) const { return (_tsdata[3] >> 6) & 0x3; }
76  //3.2 2 bit adaptation_field_control
77  // (01-no adaptation field,payload only
78  // 10-adaptation field only,no payload
79  // 11-adaptation field followed by payload
80  // 00-reserved)
81  unsigned int AdaptationFieldControl(void) const {
82  return (_tsdata[3] >> 4) & 0x3;
83  }
84  //3.4 4 bit continuity counter (should cycle 0->15 in sequence
85  // for each PID; if skip, we lost a packet; if dup, we can
86  // ignore packet)
87  unsigned int ContinuityCounter(void) const { return _tsdata[3] & 0xf; }
88 
89  // shortcuts
90  bool Scrambled(void) const { return bool(_tsdata[3]&0x80); }
91  bool HasAdaptationField(void) const { return bool(_tsdata[3] & 0x20); }
92  size_t AdaptationFieldSize(void) const
93  { return (HasAdaptationField() ? static_cast<size_t>(_tsdata[4]) : 0); }
94  bool HasPayload(void) const { return bool(_tsdata[3] & 0x10); }
95 
96  bool GetDiscontinuityIndicator(void) const
97  { return AdaptationFieldSize() > 0 && bool(data()[5] & 0x80); }
98 
99  bool HasPCR(void) const { return AdaptationFieldSize() > 0 &&
100  bool(data()[5] & 0x10); }
101 
102  /*
103  The PCR field is a 42 bit field in the adaptation field of the
104  Transport Stream. The PCR field consists of a 9 bit part that
105  increments at a 27MHz rate and a 33 bit part that increments at
106  a 90kHz rate (when the 27MHz part rolls over).
107  */
108  // The high-order 33bits (of the 48 total) are the 90kHz clock
109  int64_t GetPCRbase(void) const
110  { return ((static_cast<int64_t>(data()[6]) << 25) |
111  (static_cast<int64_t>(data()[7]) << 17) |
112  (static_cast<int64_t>(data()[8]) << 9) |
113  (static_cast<int64_t>(data()[9]) << 1) |
114  (data()[10] >> 7)); }
115 
116  // The low-order 9 bits (of the 48 total) are the 27MHz clock
117  int32_t GetPCRext(void) const
118  { return (((static_cast<int32_t>(data()[10]) & 0x1) << 8) |
119  static_cast<int32_t>(data()[11])); }
120 
121  // PCR in a 27MHz clock
122  int64_t GetPCRraw(void) const
123  { return ((GetPCRbase() * 300) + GetPCRext()); }
124 
125  // PCR as a time point
126  TimePoint GetPCR(void) const
127  { return TimePoint(std::chrono::microseconds(GetPCRraw() / 27)); }
128 
129  void SetTransportError(bool err) {
130  if (err) _tsdata[1] |= 0x80; else _tsdata[1] &= (0xff-(0x80));
131  }
132  void SetPayloadStart(bool start) {
133  if (start) _tsdata[1] |= 0x40; else _tsdata[1] &= (0xff-0x40);
134  }
135  void SetPriority(bool priority) {
136  if (priority) _tsdata[1] |= 0x20; else _tsdata[1] &= (0xff-0x20);
137  }
138  void SetPID(unsigned int pid) {
139  _tsdata[1] = ((pid >> 8) & 0x1F) | (_tsdata[1] & 0xE0);
140  _tsdata[2] = (pid & 0xFF);
141  }
142  void SetScrambled(unsigned int scr) {
143  _tsdata[3] = (_tsdata[3] & (0xff-(0x3<<6))) | (scr<<6);
144  }
145  void SetAdaptationFieldControl(unsigned int afc) {
146  _tsdata[3] = (_tsdata[3] & 0xcf) | (afc&0x3)<<4;
147  }
148  void SetContinuityCounter(unsigned int cc) {
149  _tsdata[3] = (_tsdata[3] & 0xf0) | (cc & 0xf);
150  }
151 
152  const unsigned char* data(void) const { return _tsdata; }
153  unsigned char* data(void) { return _tsdata; }
154 
155  static const unsigned int kHeaderSize;
156  static const unsigned char kPayloadOnlyHeader[4];
157  private:
158  unsigned char _tsdata[4];
159 };
160 
167 {
168  friend class PESPacket;
169  public:
170  /* note: payload is intentionally left uninitialized */
171  // cppcheck-suppress uninitMemberVar
172  TSPacket(void) : TSHeader() { }
173 
175  {
176  TSPacket *pkt = new TSPacket();
177  pkt->InitHeader(kPayloadOnlyHeader);
178  memset(pkt->_tspayload, 0xFF, kPayloadSize);
179  pkt->SetStartOfFieldPointer(0);
180  return pkt;
181  }
182 
183  inline TSPacket* CreateClone(void) const {
184  TSPacket *pkt = new TSPacket();
185  memcpy(pkt, this, kSize);
186  return pkt;
187  }
188 
189  void InitPayload(const unsigned char *payload)
190  {
191  if (payload)
192  memcpy(_tspayload, payload, kPayloadSize);
193  }
194 
195  void InitPayload(const unsigned char *payload, uint size)
196  {
197  if (payload)
198  memcpy(_tspayload, payload, size);
199  else
200  size = 0;
201 
202  if (size < TSPacket::kPayloadSize)
203  memset(_tspayload + size, 0xff, TSPacket::kPayloadSize - size);
204  }
205 
206  // This points outside the TSHeader data, but is declared here because
207  // it is used for the different types of packets that employ a TS Header
208  unsigned int AFCOffset(void) const { // only works if AFC fits in TSPacket
209  return HasAdaptationField() ? _tspayload[0]+1+4 : 4;
210  }
211 
212  //4.0 8 bits, iff payloadStart(), points to start of field
213  unsigned int StartOfFieldPointer(void) const
214  { return _tspayload[AFCOffset()-4]; }
216  { _tspayload[AFCOffset()-4] = sof; }
217 
218  QString toString(void) const;
219 
220  static const unsigned int kSize;
221  static const unsigned int kPayloadSize;
222  static const unsigned int kDVBEmissionSize;
223  static const unsigned int kISDBEmissionSize;
224  static const unsigned int k8VSBEmissionSize;
225  static const TSPacket *kNullPacket;
226  private:
227  unsigned char _tspayload[184];
228 };
229 
230 #if 0 /* not used yet */
231 
234 class MTV_PUBLIC TSDVBEmissionPacket : public TSPacket
235 {
236  private:
237  unsigned char _tsfec[16];
238 };
239 
243 class MTV_PUBLIC TSISDBEmissionPacket : public TSPacket
244 {
245  private:
246  unsigned char _tsfec[16];
247 };
248 
252 class MTV_PUBLIC TS8VSBEmissionPacket : public TSPacket
253 {
254  private:
255  unsigned char _tsfec[20];
256 };
257 #endif
258 
259 #endif // _TS_PACKET_H_
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:166
static const unsigned int kHeaderSize
Definition: tspacket.h:155
static TSPacket * CreatePayloadOnlyPacket(void)
Definition: tspacket.h:174
bool Priority(void) const
Definition: tspacket.h:69
TSHeader(int cc)
Definition: tspacket.h:38
Definition: cc.h:13
bool HasAdaptationField(void) const
Definition: tspacket.h:91
void InitPayload(const unsigned char *payload)
Definition: tspacket.h:189
unsigned char _tspayload[184]
Definition: tspacket.h:227
void SetStartOfFieldPointer(uint sof)
Definition: tspacket.h:215
std::chrono::time_point< Clock, std::chrono::microseconds > TimePoint
Definition: tspacket.h:28
QString toString(MarkTypes type)
#define SYNC_BYTE
Definition: tspacket.h:15
bool
Definition: pxsup2dast.c:30
unsigned int ContinuityCounter(void) const
Definition: tspacket.h:87
unsigned int uint
Definition: compat.h:140
size_t AdaptationFieldSize(void) const
Definition: tspacket.h:92
void SetContinuityCounter(unsigned int cc)
Definition: tspacket.h:148
void SetTransportError(bool err)
Definition: tspacket.h:129
TSHeader(void)
Definition: tspacket.h:30
Used to access header of a TSPacket.
Definition: tspacket.h:24
static const unsigned int kPayloadSize
Definition: tspacket.h:221
unsigned int StartOfFieldPointer(void) const
Definition: tspacket.h:213
unsigned int AFCOffset(void) const
Definition: tspacket.h:208
int32_t GetPCRext(void) const
Definition: tspacket.h:117
bool PayloadStart(void) const
Definition: tspacket.h:67
void SetScrambled(unsigned int scr)
Definition: tspacket.h:142
#define MTV_PUBLIC
Definition: mythtvexp.h:15
std::chrono::steady_clock Clock
Definition: tspacket.h:27
void SetAdaptationFieldControl(unsigned int afc)
Definition: tspacket.h:145
bool HasSync(void) const
Definition: tspacket.h:61
bool HasPayload(void) const
Definition: tspacket.h:94
unsigned char * data(void)
Definition: tspacket.h:153
unsigned int AdaptationFieldControl(void) const
Definition: tspacket.h:81
TimePoint GetPCR(void) const
Definition: tspacket.h:126
TSPacket(void)
Definition: tspacket.h:172
int64_t GetPCRbase(void) const
Definition: tspacket.h:109
const unsigned char * data(void) const
Definition: tspacket.h:152
unsigned int ScramblingControl(void) const
Definition: tspacket.h:75
void SetPID(unsigned int pid)
Definition: tspacket.h:138
bool TransportError(void) const
Definition: tspacket.h:64
int64_t GetPCRraw(void) const
Definition: tspacket.h:122
static const TSPacket * kNullPacket
Definition: tspacket.h:225
void SetPayloadStart(bool start)
Definition: tspacket.h:132
bool GetDiscontinuityIndicator(void) const
Definition: tspacket.h:96
static const unsigned int kSize
Definition: tspacket.h:220
unsigned int PID(void) const
Definition: tspacket.h:71
void SetPriority(bool priority)
Definition: tspacket.h:135
static const unsigned int k8VSBEmissionSize
Definition: tspacket.h:224
bool Scrambled(void) const
Definition: tspacket.h:90
Allows us to transform TS packets to PES packets, which are used to hold multimedia streams and very ...
Definition: pespacket.h:25
void InitPayload(const unsigned char *payload, uint size)
Definition: tspacket.h:195
TSPacket * CreateClone(void) const
Definition: tspacket.h:183
static const unsigned int kDVBEmissionSize
Definition: tspacket.h:222
static int x3
Definition: mythsocket.cpp:62
static const unsigned int kISDBEmissionSize
Definition: tspacket.h:223
bool HasPCR(void) const
Definition: tspacket.h:99
static int x1
Definition: mythsocket.cpp:60
void InitHeader(const unsigned char *header)
Definition: tspacket.h:47