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