MythTV  master
pespacket.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // Copyright (c) 2003-2004, Daniel Thor Kristjansson
3 #ifndef PES_PACKET_H
4 #define PES_PACKET_H
5 
6 /*
7  max length of PSI table = 1024 bytes
8  max length of private_section = 4096 bytes
9 */
10 
11 #include <vector>
12 
13 using AspectArray = std::array<float,16>;
14 
16 
17 #include "tspacket.h"
18 
19 MTV_PUBLIC unsigned char *pes_alloc(uint size);
20 MTV_PUBLIC void pes_free(unsigned char *ptr);
21 
28 {
29  protected:
31  PESPacket() = default;
32 
33  public:
34  // does not create it's own data
35  explicit PESPacket(const unsigned char *pesdata)
36  : m_pesData(const_cast<unsigned char*>(pesdata)),
37  m_fullBuffer(const_cast<unsigned char*>(pesdata))
38  {
39  m_badPacket = !VerifyCRC();
40  m_pesDataSize = std::max(((int)Length())-1 + (PESPacket::HasCRC() ? 4 : 0), 0);
41  }
42  explicit PESPacket(const std::vector<uint8_t> &pesdata)
43  : m_pesData(const_cast<unsigned char*>(pesdata.data())),
44  m_fullBuffer(const_cast<unsigned char*>(pesdata.data()))
45  {
46  m_badPacket = !VerifyCRC();
47  m_pesDataSize = std::max(((int)Length())-1 + (PESPacket::HasCRC() ? 4 : 0), 0);
48  }
49 
50  // Deleted functions should be public.
51  //const PESPacket& operator=(const PESPacket& pkt);
52  PESPacket& operator=(const PESPacket& pkt) = delete;
53 
54  // may be modified
55  PESPacket(const PESPacket& pkt)
56  : m_psiOffset(pkt.m_psiOffset),
57  m_ccLast(pkt.m_ccLast),
58  m_pesDataSize(pkt.m_pesDataSize),
59  m_allocSize(pkt.m_allocSize),
60  m_badPacket(pkt.m_badPacket)
61  { // clone
62  if (!m_allocSize)
63  m_allocSize = pkt.m_pesDataSize + (pkt.m_pesData - pkt.m_fullBuffer);
64 
65  m_fullBuffer = pes_alloc(m_allocSize);
66  memcpy(m_fullBuffer, pkt.m_fullBuffer, m_allocSize);
67  m_pesData = m_fullBuffer + (pkt.m_pesData - pkt.m_fullBuffer);
68  }
69 
70  // At this point we should have the entire VCT table in buffer
71  // at (buffer - 8), and without the tspacket 4 byte header
72 
73  //if (TableID::TVCT == table_id)
74  //VirtualChannelTable vct;
75 
76  virtual ~PESPacket()
77  {
78  if (IsClone())
79  pes_free(m_fullBuffer);
80 
81  m_fullBuffer = nullptr;
82  m_pesData = nullptr;
83  }
84 
85  bool IsClone() const { return bool(m_allocSize); }
86 
87  // return true if complete or broken
88  bool AddTSPacket(const TSPacket* tspacket, int cardid, bool &broken);
89 
90  bool IsGood() const { return !m_badPacket; }
91 
92  const TSHeader* tsheader() const
93  { return reinterpret_cast<const TSHeader*>(m_fullBuffer); }
95  { return reinterpret_cast<TSHeader*>(m_fullBuffer); }
96 
97  void GetAsTSPackets(std::vector<TSPacket> &output, uint cc) const;
98 
99  // m_pesData[-3] == 0, m_pesData[-2] == 0, m_pesData[-1] == 1
100  uint StreamID() const { return m_pesData[0]; }
101  uint Length() const
102  { return (m_pesData[1] & 0x0f) << 8 | m_pesData[2]; }
103  // 2 bits "10"
104  // 2 bits "PES_scrambling_control (0 not scrambled)
106  { return (m_pesData[3] & 0x30) >> 4; }
108  bool HighPriority() const { return ((m_pesData[3] & 0x8) >> 3) != 0; }
110  bool DataAligned() const { return ((m_pesData[3] & 0x4) >> 2) != 0; }
115  bool CopyRight() const { return ((m_pesData[3] & 0x2) >> 1) != 0; }
117  bool OriginalRecording() const { return (m_pesData[3] & 0x1) != 0; }
118 
120  bool HasPTS() const { return ((m_pesData[4] & 0x80) >> 7) != 0; }
122  bool HasDTS() const { return ((m_pesData[4] & 0x40) >> 6) != 0; }
124  bool HasESCR() const { return ((m_pesData[4] & 0x20) >> 5) != 0; }
126  bool HasESR() const { return ((m_pesData[4] & 0x10) >> 4) != 0; }
128  bool HasDSM() const { return ((m_pesData[4] & 0x8) >> 3) != 0; }
130  bool HasACI() const { return ((m_pesData[4] & 0x4) >> 2) != 0; }
132  virtual bool HasCRC() const { return ((m_pesData[4] & 0x2) >> 1) != 0; }
134  bool HasExtensionFlags() const { return (m_pesData[4] & 0x1) != 0; }
135 
137  uint64_t PTS(void) const
138  {
139  int i = 6;
140  return
141  (uint64_t(m_pesData[i+0] & 0x0e) << 29) |
142  (uint64_t(m_pesData[i+1] ) << 22) |
143  (uint64_t(m_pesData[i+2] & 0xfe) << 14) |
144  (uint64_t(m_pesData[i+3] ) << 7) |
145  (uint64_t(m_pesData[i+4] & 0xfe) >> 1);
146  }
148  uint64_t DTS(void) const
149  {
150  int i = 6+(HasPTS()?5:0);
151  return
152  (uint64_t(m_pesData[i+0] & 0x0e) << 29) |
153  (uint64_t(m_pesData[i+1] ) << 22) |
154  (uint64_t(m_pesData[i+2] & 0xfe) << 14) |
155  (uint64_t(m_pesData[i+3] ) << 7) |
156  (uint64_t(m_pesData[i+4] & 0xfe) >> 1);
157  }
158 
159  // 8 bits PES Header Length
160  // variable length -- pes header fields
161  // variable length -- pes data block
162 
163  uint TSSizeInBuffer() const { return m_pesDataSize; }
164  uint PSIOffset() const { return m_psiOffset; }
165 
166  const unsigned char* pesdata() const { return m_pesData; }
167  unsigned char* pesdata() { return m_pesData; }
168 
169  const unsigned char* data() const { return m_fullBuffer; }
170  unsigned char* data() { return m_fullBuffer; }
171 
172  void SetStreamID(uint id) { m_pesData[0] = id; }
173  void SetLength(uint len)
174  {
175  m_pesData[1] = (m_pesData[1] & 0xf0) | ((len>>8) & 0x0f);
176  m_pesData[2] = len & 0xff;
177  }
179  {
180  len += 4 /* for CRC */;
181  len -= 3 /* for data before data last byte of length */;
182  SetLength(len);
183  }
184 
185  void SetPSIOffset(uint offset)
186  {
187  m_psiOffset = offset;
188  m_pesData = m_fullBuffer + m_psiOffset + 1;
189  }
190 
191  uint CRC(void) const
192  {
193  if (!HasCRC() || (Length() < 1))
194  return kTheMagicNoCRCCRC;
195  uint offset = Length() - 1;
196  return ((m_pesData[offset+0]<<24) |
197  (m_pesData[offset+1]<<16) |
198  (m_pesData[offset+2]<<8) |
199  (m_pesData[offset+3]));
200  }
201 
202  void SetCRC(uint crc)
203  {
204  if (Length() < 1)
205  return;
206 
207  uint offset = Length() - 1;
208  m_pesData[offset+0] = (crc & 0xff000000) >> 24;
209  m_pesData[offset+1] = (crc & 0x00ff0000) >> 16;
210  m_pesData[offset+2] = (crc & 0x0000ff00) >> 8;
211  m_pesData[offset+3] = (crc & 0x000000ff);
212  }
213 
214  uint CalcCRC(void) const;
215  bool VerifyCRC(void) const;
216  bool VerifyCRC(int cardid, int pid) const;
217 
218  protected:
219  void Finalize() { SetCRC(CalcCRC()); }
220 
221  unsigned char *m_pesData { nullptr };
222  unsigned char *m_fullBuffer { nullptr };
223 
224  uint m_psiOffset { 0 };
225  uint m_ccLast { 255 };
226  uint m_pesDataSize { 0 };
227  uint m_allocSize { 0 };
228  bool m_badPacket { false };
229 
230  // FIXME re-read the specs and follow all negations to find out the
231  // initial value of the CRC function when its being returned
232  static const uint kTheMagicNoCRCCRC = 0xFFFFFFFF;
233 
234  public:
235  static constexpr uint kMpegCRCSize { 4 };
236 };
237 
239 {
240  public:
241  uint width(void) const { return (m_data[0] <<4) | (m_data[1]>>4); }
242  uint height(void) const { return ((m_data[1] & 0xf)<<8) | m_data[2]; }
243  uint aspectNum(void) const { return m_data[3] >> 4; }
244  uint fpsNum(void) const { return m_data[3] & 0xf; }
245  float fps(void) const { return kMpeg2Fps[fpsNum()]; }
246  float aspect(bool mpeg1) const;
247 
248  private:
249  SequenceHeader() {;} // only used via reinterpret cast
251 
252  std::array<unsigned char,11> m_data {};
253  static const AspectArray kMpeg1Aspect;
254  static const AspectArray kMpeg2Aspect;
255  static const AspectArray kMpeg2Fps;
256 };
257 
258 #endif // PES_PACKET_H
PESPacket::m_pesData
unsigned char * m_pesData
Pointer to PES data in full buffer.
Definition: pespacket.h:221
PESPacket::m_pesDataSize
uint m_pesDataSize
Number of data bytes (TS header + PES data)
Definition: pespacket.h:226
bool
bool
Definition: pxsup2dast.c:30
PESPacket::ScramblingControl
uint ScramblingControl() const
Definition: pespacket.h:105
SequenceHeader::fpsNum
uint fpsNum(void) const
Definition: pespacket.h:244
PESPacket::CopyRight
bool CopyRight() const
1 bit If true packet may contain copy righted material and is known to have once contained materiale ...
Definition: pespacket.h:115
SequenceHeader::kMpeg1Aspect
static const AspectArray kMpeg1Aspect
Definition: pespacket.h:253
SequenceHeader::m_data
std::array< unsigned char, 11 > m_data
Definition: pespacket.h:252
PESPacket::IsClone
bool IsClone() const
Definition: pespacket.h:85
PESPacket::SetTotalLength
void SetTotalLength(uint len)
Definition: pespacket.h:178
x2
static int x2
Definition: mythsocket.cpp:51
PESPacket::pesdata
const unsigned char * pesdata() const
Definition: pespacket.h:166
PESPacket::~PESPacket
virtual ~PESPacket()
Definition: pespacket.h:76
PESPacket::tsheader
const TSHeader * tsheader() const
Definition: pespacket.h:92
cc
Definition: cc.h:9
PESPacket::SetCRC
void SetCRC(uint crc)
Definition: pespacket.h:202
SequenceHeader::fps
float fps(void) const
Definition: pespacket.h:245
PESPacket::HighPriority
bool HighPriority() const
1 bit Indicates if this is a high priority packet
Definition: pespacket.h:108
PESPacket::PSIOffset
uint PSIOffset() const
Definition: pespacket.h:164
SequenceHeader::height
uint height(void) const
Definition: pespacket.h:242
PESPacket::StreamID
uint StreamID() const
Definition: pespacket.h:100
PESPacket::tsheader
TSHeader * tsheader()
Definition: pespacket.h:94
PESPacket::PESPacket
PESPacket(const std::vector< uint8_t > &pesdata)
Definition: pespacket.h:42
SequenceHeader::SequenceHeader
SequenceHeader()
Definition: pespacket.h:249
PESPacket::SetPSIOffset
void SetPSIOffset(uint offset)
Definition: pespacket.h:185
PESPacket::DataAligned
bool DataAligned() const
1 bit Data alignment indicator (must be 0 for video)
Definition: pespacket.h:110
x4
static int x4
Definition: mythsocket.cpp:53
PESPacket::data
const unsigned char * data() const
Definition: pespacket.h:169
mythlogging.h
SetLength
static uint8_t * SetLength(uint8_t *Data, int Length)
Definition: dvbci.cpp:117
PESPacket::data
unsigned char * data()
Definition: pespacket.h:170
TSPacket
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:205
SequenceHeader::kMpeg2Fps
static const AspectArray kMpeg2Fps
Definition: pespacket.h:255
x1
static int x1
Definition: mythsocket.cpp:50
tspacket.h
PESPacket::HasACI
bool HasACI() const
1 bit Additional Copy Info field is present
Definition: pespacket.h:130
PESPacket::Length
uint Length() const
Definition: pespacket.h:101
PESPacket::IsGood
bool IsGood() const
Definition: pespacket.h:90
PESPacket::TSSizeInBuffer
uint TSSizeInBuffer() const
Definition: pespacket.h:163
uint
unsigned int uint
Definition: compat.h:79
SequenceHeader::aspect
float aspect(bool mpeg1) const
Returns the screen aspect ratio.
Definition: pespacket.cpp:223
PESPacket::HasDTS
bool HasDTS() const
1 bit Decoding Time Stamp field is present
Definition: pespacket.h:122
PESPacket::Finalize
void Finalize()
Definition: pespacket.h:219
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
PESPacket::OriginalRecording
bool OriginalRecording() const
1 bit Original Recording
Definition: pespacket.h:117
AspectArray
std::array< float, 16 > AspectArray
Definition: pespacket.h:13
SequenceHeader::width
uint width(void) const
Definition: pespacket.h:241
SequenceHeader::kMpeg2Aspect
static const AspectArray kMpeg2Aspect
The negative values are screen aspect ratios, while the positive ones are pixel aspect ratios.
Definition: pespacket.h:254
PESPacket::CRC
uint CRC(void) const
Definition: pespacket.h:191
SequenceHeader::aspectNum
uint aspectNum(void) const
Definition: pespacket.h:243
PESPacket::SetStreamID
void SetStreamID(uint id)
Definition: pespacket.h:172
PESPacket::PESPacket
PESPacket(const PESPacket &pkt)
Definition: pespacket.h:55
PESPacket::pesdata
unsigned char * pesdata()
Definition: pespacket.h:167
PESPacket::SetLength
void SetLength(uint len)
Definition: pespacket.h:173
PESPacket::HasESR
bool HasESR() const
1 bit Elementary Stream Rate field is present
Definition: pespacket.h:126
TSHeader
Used to access header of a TSPacket.
Definition: tspacket.h:44
PESPacket::DTS
uint64_t DTS(void) const
Decode Time Stamp, present if HasDTS() is true.
Definition: pespacket.h:148
PESPacket::HasPTS
bool HasPTS() const
1 bit Presentation Time Stamp field is present
Definition: pespacket.h:120
PESPacket::HasESCR
bool HasESCR() const
1 bit Elementary Stream Clock Reference field is present
Definition: pespacket.h:124
PESPacket::HasCRC
virtual bool HasCRC() const
1 bit Cyclic Redundancy Check present
Definition: pespacket.h:132
PESPacket::m_fullBuffer
unsigned char * m_fullBuffer
Pointer to allocated data.
Definition: pespacket.h:222
PESPacket::HasDSM
bool HasDSM() const
1 bit DSM field present (should always be false for broadcasts)
Definition: pespacket.h:128
SequenceHeader::~SequenceHeader
~SequenceHeader()
Definition: pespacket.h:250
pes_alloc
MTV_PUBLIC unsigned char * pes_alloc(uint size)
Definition: pespacket.cpp:357
SequenceHeader
Definition: pespacket.h:238
PESPacket::PTS
uint64_t PTS(void) const
Presentation Time Stamp, present if HasPTS() is true.
Definition: pespacket.h:137
output
#define output
Definition: synaesthesia.cpp:220
PESPacket::HasExtensionFlags
bool HasExtensionFlags() const
1 bit Extension flags are present
Definition: pespacket.h:134
PESPacket::PESPacket
PESPacket(const unsigned char *pesdata)
Definition: pespacket.h:35
pes_free
MTV_PUBLIC void pes_free(unsigned char *ptr)
Definition: pespacket.cpp:369