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