Browse Source

Add TS resync; close #131, #85

Dominic Szablewski 8 years ago
parent
commit
7bdf1079ec
1 changed files with 44 additions and 6 deletions
  1. 44 6
      src/ts.js

+ 44 - 6
src/ts.js View File

@@ -32,9 +32,7 @@ TS.prototype.write = function(buffer) {
32 32
 		this.bits = new JSMpeg.BitBuffer(buffer);
33 33
 	}
34 34
 
35
-	while (this.bits.has(188 << 3)) {
36
-		this.parsePacket();
37
-	}
35
+	while (this.bits.has(188 << 3) && this.parsePacket()) {}
38 36
 
39 37
 	var leftoverCount = this.bits.byteLength - (this.bits.index >> 3);
40 38
 	this.leftoverBytes = leftoverCount > 0
@@ -43,12 +41,15 @@ TS.prototype.write = function(buffer) {
43 41
 };
44 42
 
45 43
 TS.prototype.parsePacket = function() {
46
-	var end = (this.bits.index >> 3) + 188;
47
-
44
+	// Check if we're in sync with packet boundaries; attempt to resync if not.
48 45
 	if (this.bits.read(8) !== 0x47) {
49
-		throw("Sync Token not found");
46
+		if (!this.resync()) {
47
+			// Couldn't resync; maybe next time...
48
+			return false;
49
+		}
50 50
 	}
51 51
 
52
+	var end = (this.bits.index >> 3) + 187;
52 53
 	var transportError = this.bits.read(1),
53 54
 		payloadStart = this.bits.read(1),
54 55
 		transportPriority = this.bits.read(1),
@@ -148,6 +149,43 @@ TS.prototype.parsePacket = function() {
148 149
 	}
149 150
 
150 151
 	this.bits.index = end << 3;
152
+	return true;
153
+};
154
+
155
+TS.prototype.resync = function() {
156
+	// Check if we have enough data to attempt a resync. We need 5 full packets.
157
+	if (!this.bits.has((188 * 6) << 3)) {
158
+		return false;
159
+	}
160
+
161
+	var byteIndex = this.bits.index >> 3;
162
+
163
+	// Look for the first sync token in the first 187 bytes
164
+	for (var i = 0; i < 187; i++) {
165
+		if (this.bits.bytes[byteIndex + i] === 0x47) {
166
+
167
+			// Look for 5 more sync tokens, each 188 bytes appart
168
+			var foundSync = true;
169
+			for (var j = 1; j < 5; j++) {
170
+				if (this.bits.bytes[byteIndex + i + 188 * j] !== 0x47) {
171
+					foundSync = false;
172
+					break;
173
+				}
174
+			}
175
+
176
+			if (foundSync) {
177
+				this.bits.index = (byteIndex + i + 1) << 3;
178
+				return true;
179
+			}
180
+		}
181
+	}
182
+
183
+	// In theory, we shouldn't arrive here. If we do, we had enough data but
184
+	// still didn't find sync - this can only happen if we were fed garbage
185
+	// data. Check your source!
186
+	console.warn('JSMpeg: Possible garbage data. Skipping.');
187
+	this.bits.skip(187 << 3);
188
+	return false;
151 189
 };
152 190
 
153 191
 TS.prototype.packetStart = function(pi, pts, payloadLength) {