Skip to content

Commit d381f2b

Browse files
Merge pull request #17 from Unit-X/star-1305-fix-demuxer-looses-sync
Star 1305 fix demuxer looses sync
2 parents 02e8a06 + b3a899a commit d381f2b

File tree

11 files changed

+511
-318
lines changed

11 files changed

+511
-318
lines changed

.github/workflows/unittests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
- name: get the ts test file
1717
run: |
1818
wget https://github.com/andersc/assets/raw/master/bars.ts
19+
cp bars.ts bars-github.ts
1920
- name: build unit tests
2021
run: |
2122
mkdir build

mpegts/common.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ void writePts(SimpleBuffer &rSb, uint32_t lFb, uint64_t lPts) {
1616
uint32_t lVal;
1717

1818
lVal = lFb << 4 | (((lPts >> 30) & 0x07) << 1) | 1;
19-
rSb.write1Byte((int8_t) lVal);
19+
rSb.write1Byte((uint8_t) lVal);
2020

2121
lVal = (((lPts >> 15) & 0x7fff) << 1) | 1;
22-
rSb.write2Bytes((int16_t) lVal);
22+
rSb.write2Bytes((uint16_t) lVal);
2323

2424
lVal = (((lPts) & 0x7fff) << 1) | 1;
25-
rSb.write2Bytes((int16_t) lVal);
25+
rSb.write2Bytes((uint16_t) lVal);
2626
}
2727

2828
uint64_t readPts(SimpleBuffer &rSb) {

mpegts/mpegts_demuxer.cpp

Lines changed: 268 additions & 168 deletions
Large diffs are not rendered by default.

mpegts/mpegts_demuxer.h

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818

1919
namespace mpegts {
2020

21-
class MpegTsDemuxer {
21+
class MpegTsDemuxer final {
2222
public:
2323

24-
MpegTsDemuxer();
24+
MpegTsDemuxer() = default;
2525

26-
virtual ~MpegTsDemuxer();
26+
~MpegTsDemuxer() = default;
2727

2828
uint8_t decode(SimpleBuffer &rIn);
2929

@@ -33,8 +33,9 @@ class MpegTsDemuxer {
3333
std::function<void(uint16_t pid, uint8_t expectedCC, uint8_t actualCC)> ccErrorCallback = nullptr;
3434

3535
// stream, pid
36+
const int kPatId = 0x0;
3637
std::map<uint8_t, int> mStreamPidMap;
37-
int mPmtId;
38+
int mPmtId = 0;
3839

3940
// PAT
4041
PATHeader mPatHeader;
@@ -45,16 +46,46 @@ class MpegTsDemuxer {
4546
bool mPmtIsValid = false;
4647

4748
private:
48-
// pid, Elementary data frame
49+
// Check that the CC is incremented according to spec. ccErrorCallback is called on error.
50+
void checkContinuityCounter(const TsHeader &rTsHeader, uint8_t discontinuityIndicator);
51+
52+
// Check that the current position in buffer is pointing to a sync byte and if the buffer is larger than a TS packet,
53+
// the function checks that the first byte after the TS packet is also a sync byte. Returns true if the buffer is in
54+
// sync with the TS packet boundaries, otherwise false.
55+
static bool checkSync(SimpleBuffer& rIn);
56+
57+
// Parse a TS packet, the input buffer should be aligned to the start of a TS packet and the buffer should be at least
58+
// 188 bytes long.
59+
void parseTsPacket(SimpleBuffer& rSb);
60+
61+
// Parse the adaptation field, will look for PCR values and pass to the pcrOutCallback. Returns true if parsing was
62+
// successful, otherwise false. The randomAccessIndicator is set to 1 if the packet contains a random access point.
63+
bool parseAdaptationField(const TsHeader& rTsHeader, SimpleBuffer& rSb, size_t bytesLeftInPacket, uint8_t& randomAccessIndicator);
64+
65+
// Parse the PAT table
66+
bool parsePat(const TsHeader& rTsHeader, SimpleBuffer& rSb);
67+
68+
// Parse the PMT table
69+
bool parsePmt(const TsHeader& rTsHeader, SimpleBuffer& rSb);
70+
71+
// Parse the PES data and create EsFrames. The EsFrames are passed to the esOutCallback.
72+
bool parsePes(const TsHeader& rTsHeader, uint8_t randomAccessIndicator, SimpleBuffer& rSb, size_t payloadSize);
73+
74+
// Parse the PCR value from the adaptation field and pass to the pcrOutCallback.
75+
void parsePcr(const AdaptationFieldHeader& rAdaptionField, SimpleBuffer& rSb) const;
76+
77+
// Check if the PCR value should be parsed based on the PID and the pcrOutCallback.
78+
bool shouldParsePcr(uint16_t pid) const;
79+
80+
// Elementary stream data frames
4981
std::map<int, EsFrame> mEsFrames;
50-
int mPcrId;
82+
int mPcrId = 0;
5183
SimpleBuffer mRestData;
5284

5385
// Continuity counters. Map from PID to current CC value.
5486
std::unordered_map<uint16_t, uint8_t> mCCs;
5587

56-
// Check that the CC is incremented according to spec. ccErrorCallback is called on error.
57-
void checkContinuityCounter(const TsHeader &rTsHeader, uint8_t discontinuityIndicator);
88+
size_t mBytesDroppedToRecoverSync = 0; // Keep track of how many bytes were dropped to recover sync
5889
};
5990

6091
}

mpegts/simple_buffer.cpp

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,63 @@
11
#include "simple_buffer.h"
2-
#include <assert.h>
2+
3+
#include <cstring>
34
#include <iterator>
45

6+
#include <cassert>
7+
58
namespace mpegts {
69

7-
SimpleBuffer::SimpleBuffer()
8-
: mPos(0)
9-
{
10-
}
10+
SimpleBuffer::SimpleBuffer() = default;
1111

1212
SimpleBuffer::SimpleBuffer(int32_t size, int8_t value)
13-
: mPos(0)
1413
{
1514
mData = std::vector<uint8_t>(size, value);
1615
}
1716

18-
SimpleBuffer::~SimpleBuffer()
19-
{
20-
}
17+
SimpleBuffer::~SimpleBuffer() = default;
2118

22-
void SimpleBuffer::write1Byte(int8_t val)
19+
void SimpleBuffer::write1Byte(uint8_t val)
2320
{
2421
mData.push_back(val);
2522
}
2623

27-
void SimpleBuffer::write2Bytes(int16_t val)
24+
void SimpleBuffer::write2Bytes(uint16_t val)
2825
{
29-
char *p = (char *)&val;
26+
uint8_t *p = reinterpret_cast<uint8_t*>(&val);
3027

3128
for (int i = 1; i >= 0; --i) {
3229
mData.push_back(p[i]);
3330
}
3431
}
3532

36-
void SimpleBuffer::write3Bytes(int32_t val)
33+
void SimpleBuffer::write3Bytes(uint32_t val)
3734
{
38-
char *p = (char *)&val;
35+
uint8_t *p = reinterpret_cast<uint8_t*>(&val);
3936

4037
for (int i = 2; i >= 0; --i) {
4138
mData.push_back(p[i]);
4239
}
4340
}
4441

45-
void SimpleBuffer::write4Bytes(int32_t val)
42+
void SimpleBuffer::write4Bytes(uint32_t val)
4643
{
47-
char *p = (char *)&val;
44+
uint8_t *p = reinterpret_cast<uint8_t*>(&val);
4845

4946
for (int i = 3; i >= 0; --i) {
5047
mData.push_back(p[i]);
5148
}
5249
}
5350

54-
void SimpleBuffer::write8Bytes(int64_t val)
51+
void SimpleBuffer::write8Bytes(uint64_t val)
5552
{
56-
char *p = (char *)&val;
53+
uint8_t *p = reinterpret_cast<uint8_t*>(&val);
5754

5855
for (int i = 7; i >= 0; --i) {
5956
mData.push_back(p[i]);
6057
}
6158
}
6259

63-
void SimpleBuffer::append(const uint8_t* bytes, int size)
60+
void SimpleBuffer::append(const uint8_t* bytes, size_t size)
6461
{
6562
if (!bytes || size <= 0) {
6663
#ifdef DEBUG
@@ -72,7 +69,7 @@ void SimpleBuffer::append(const uint8_t* bytes, int size)
7269
mData.insert(mData.end(), bytes, bytes + size);
7370
}
7471

75-
void SimpleBuffer::prepend(const uint8_t* bytes, int size)
72+
void SimpleBuffer::prepend(const uint8_t* bytes, size_t size)
7673
{
7774
if (!bytes || size <= 0) {
7875
#ifdef DEBUG
@@ -84,22 +81,22 @@ void SimpleBuffer::prepend(const uint8_t* bytes, int size)
8481
mData.insert(mData.begin(), bytes, bytes + size);
8582
}
8683

87-
int8_t SimpleBuffer::read1Byte()
84+
uint8_t SimpleBuffer::read1Byte()
8885
{
8986
assert(require(1));
9087

91-
int8_t val = mData.at(0 + mPos);
88+
uint8_t val = mData.at(0 + mPos);
9289
mPos++;
9390

9491
return val;
9592
}
9693

97-
int16_t SimpleBuffer::read2Bytes()
94+
uint16_t SimpleBuffer::read2Bytes()
9895
{
9996
assert(require(2));
10097

101-
int16_t val = 0;
102-
char *p = (char *)&val;
98+
uint16_t val = 0;
99+
uint8_t *p = reinterpret_cast<uint8_t*>(&val);
103100

104101
for (int i = 1; i >= 0; --i) {
105102
p[i] = mData.at(0 + mPos);
@@ -109,12 +106,12 @@ int16_t SimpleBuffer::read2Bytes()
109106
return val;
110107
}
111108

112-
int32_t SimpleBuffer::read3Bytes()
109+
uint32_t SimpleBuffer::read3Bytes()
113110
{
114111
assert(require(3));
115112

116-
int32_t val = 0;
117-
char *p = (char *)&val;
113+
uint32_t val = 0;
114+
uint8_t *p = reinterpret_cast<uint8_t*>(&val);
118115

119116
for (int i = 2; i >= 0; --i) {
120117
p[i] = mData.at(0 + mPos);
@@ -124,12 +121,12 @@ int32_t SimpleBuffer::read3Bytes()
124121
return val;
125122
}
126123

127-
int32_t SimpleBuffer::read4Bytes()
124+
uint32_t SimpleBuffer::read4Bytes()
128125
{
129126
assert(require(4));
130127

131128
int32_t val = 0;
132-
char *p = (char *)&val;
129+
uint8_t *p = reinterpret_cast<uint8_t*>(&val);
133130

134131
for (int i = 3; i >= 0; --i) {
135132
p[i] = mData.at(0 + mPos);
@@ -139,12 +136,12 @@ int32_t SimpleBuffer::read4Bytes()
139136
return val;
140137
}
141138

142-
int64_t SimpleBuffer::read8Bytes()
139+
uint64_t SimpleBuffer::read8Bytes()
143140
{
144141
assert(require(8));
145142

146-
int64_t val = 0;
147-
char *p = (char *)&val;
143+
uint64_t val = 0;
144+
uint8_t *p = reinterpret_cast<uint8_t*>(&val);
148145

149146
for (int i = 7; i >= 0; --i) {
150147
p[i] = mData.at(0 + mPos);
@@ -154,46 +151,56 @@ int64_t SimpleBuffer::read8Bytes()
154151
return val;
155152
}
156153

157-
std::string SimpleBuffer::readString(int len)
154+
std::string SimpleBuffer::readString(size_t len)
158155
{
159156
assert(require(len));
160157

161-
std::string val(*(char*)&mData[0] + mPos, len);
158+
std::string val(reinterpret_cast<char*>(&mData.at(mPos)), len);
162159
mPos += len;
163160

164161
return val;
165162
}
166163

167-
void SimpleBuffer::skip(int size)
164+
void SimpleBuffer::skip(size_t size)
168165
{
169166
mPos += size;
170167
}
171168

172-
bool SimpleBuffer::require(int required_size)
169+
bool SimpleBuffer::require(size_t required_size) const
173170
{
174171
assert(required_size >= 0);
175172

176173
return required_size <= mData.size() - mPos;
177174
}
178175

179-
bool SimpleBuffer::empty()
176+
bool SimpleBuffer::empty() const
180177
{
181178
return mPos >= mData.size();
182179
}
183180

184-
int SimpleBuffer::size()
181+
size_t SimpleBuffer::size() const
185182
{
186183
return mData.size();
187184
}
188185

189-
int SimpleBuffer::pos()
186+
size_t SimpleBuffer::pos() const
190187
{
191188
return mPos;
192189
}
193190

194191
uint8_t* SimpleBuffer::data()
195192
{
196-
return (size() == 0) ? nullptr : &mData[0];
193+
return mData.empty() ? nullptr : &mData[0];
194+
}
195+
196+
uint8_t* SimpleBuffer::currentData()
197+
{
198+
return (mData.empty() || mPos >= mData.size()) ? nullptr : &mData[mPos];
199+
}
200+
201+
size_t SimpleBuffer::dataLeft() const
202+
{
203+
return mData.size() - mPos;
197204
}
198205

199206
void SimpleBuffer::clear()
@@ -202,7 +209,7 @@ void SimpleBuffer::clear()
202209
mData.clear();
203210
}
204211

205-
void SimpleBuffer::setData(int pos, const uint8_t* data, int len)
212+
void SimpleBuffer::setData(size_t pos, const uint8_t* data, size_t len)
206213
{
207214
if (!data) {
208215
#ifdef DEBUG
@@ -218,9 +225,7 @@ void SimpleBuffer::setData(int pos, const uint8_t* data, int len)
218225
return;
219226
}
220227

221-
for (int i = 0; i < len; i++) {
222-
mData[pos + i] = data[i];
223-
}
228+
std::memcpy(currentData(), data, len);
224229
}
225230

226231
}

0 commit comments

Comments
 (0)