Procházet zdrojové kódy

More optimizations.

Robert Nagy před 11 roky
rodič
revize
7718f809b6
1 změnil soubory, kde provedl 226 přidání a 190 odebrání
  1. 226 190
      jsmpg.js

+ 226 - 190
jsmpg.js Zobrazit soubor

@@ -520,23 +520,23 @@ jsmpeg.prototype.initBuffers = function() {
520 520
 	}
521 521
 	
522 522
 	// Allocated buffers and resize the canvas
523
-	this.currentY = new Uint8Array(this.codedSize);
523
+	this.currentY = new MaybeClampedUint8Array(this.codedSize);
524 524
 	this.currentY32 = new Uint32Array(this.currentY.buffer);
525 525
 
526
-	this.currentCr = new Uint8Array(this.codedSize >> 2);
526
+	this.currentCr = new MaybeClampedUint8Array(this.codedSize >> 2);
527 527
 	this.currentCr32 = new Uint32Array(this.currentCr.buffer);
528 528
 
529
-	this.currentCb = new Uint8Array(this.codedSize >> 2);
529
+	this.currentCb = new MaybeClampedUint8Array(this.codedSize >> 2);
530 530
 	this.currentCb32 = new Uint32Array(this.currentCb.buffer);
531 531
 	
532 532
 
533
-	this.forwardY = new Uint8Array(this.codedSize);
533
+	this.forwardY = new MaybeClampedUint8Array(this.codedSize);
534 534
 	this.forwardY32 = new Uint32Array(this.forwardY.buffer);
535 535
 
536
-	this.forwardCr = new Uint8Array(this.codedSize >> 2);
536
+	this.forwardCr = new MaybeClampedUint8Array(this.codedSize >> 2);
537 537
 	this.forwardCr32 = new Uint32Array(this.forwardCr.buffer);
538 538
 
539
-	this.forwardCb = new Uint8Array(this.codedSize >> 2);
539
+	this.forwardCb = new MaybeClampedUint8Array(this.codedSize >> 2);
540 540
 	this.forwardCb32 = new Uint32Array(this.forwardCb.buffer);
541 541
 	
542 542
 	this.canvas.width = this.width;
@@ -1204,196 +1204,232 @@ jsmpeg.prototype.dcPredictorCb;
1204 1204
 jsmpeg.prototype.blockData = null;
1205 1205
 jsmpeg.prototype.decodeBlock = function(block) {
1206 1206
 	
1207
-	var
1208
-		n = 0,
1209
-		quantMatrix;
1210
-	
1211
-	// Clear preverious data
1212
-	this.blockData.set(this.zeroBlockData);
1213
-	
1214
-	// Decode DC coefficient of intra-coded blocks
1215
-	if( this.macroblockIntra ) {
1216
-		var 
1217
-			predictor,
1218
-			dctSize;
1219
-		
1220
-		// DC prediction
1221
-		
1222
-		if( block < 4 ) {
1223
-			predictor = this.dcPredictorY;
1224
-			dctSize = this.readCode(DCT_DC_SIZE_LUMINANCE);
1225
-		}
1226
-		else {
1227
-			predictor = (block == 4 ? this.dcPredictorCr : this.dcPredictorCb);
1228
-			dctSize = this.readCode(DCT_DC_SIZE_CHROMINANCE);
1229
-		}
1230
-		
1231
-		// Read DC coeff
1232
-		if( dctSize > 0 ) {
1233
-			var differential = this.buffer.getBits(dctSize);
1234
-			if( (differential & (1 << (dctSize - 1))) != 0 ) {
1235
-				this.blockData[0] = predictor + differential;
1236
-			}
1237
-			else {
1238
-				this.blockData[0] = predictor + ((-1 << dctSize)|(differential+1));
1239
-			}
1240
-		}
1241
-		else {
1242
-			this.blockData[0] = predictor;
1243
-		}
1244
-		
1245
-		// Save predictor value
1246
-		if( block < 4 ) {
1247
-			this.dcPredictorY = this.blockData[0];
1248
-		}
1249
-		else if( block == 4 ) {
1250
-			this.dcPredictorCr = this.blockData[0];
1251
-		}
1252
-		else {
1253
-			this.dcPredictorCb = this.blockData[0];
1254
-		}
1255
-		
1256
-		// Dequantize + premultiply
1257
-		this.blockData[0] <<= (3 + 5);
1258
-		
1259
-		quantMatrix = this.intraQuantMatrix;
1260
-		n = 1;
1261
-	}
1262
-	else {
1263
-		quantMatrix = this.nonIntraQuantMatrix;
1264
-	}
1265
-	
1266
-	// Decode AC coefficients (+DC for non-intra)
1267
-	var level = 0;
1268
-	while( true ) {
1269
-		var 
1270
-			run = 0,
1271
-			coeff = this.readCode(DCT_COEFF);
1272
-		
1273
-		if( (coeff == 0x0001) && (n > 0) && (this.buffer.getBits(1) == 0) ) {
1274
-			// end_of_block
1275
-			break;
1276
-		}
1277
-		if( coeff == 0xffff ) {
1278
-			// escape
1279
-			run = this.buffer.getBits(6);
1280
-			level = this.buffer.getBits(8);
1281
-			if( level == 0 ) {
1282
-				level = this.buffer.getBits(8);
1283
-			}
1284
-			else if( level == 128 ) {
1285
-				level = this.buffer.getBits(8) - 256;
1286
-			}
1287
-			else if( level > 128 ) {
1288
-				level = level - 256;
1289
-			}
1290
-		}
1291
-		else {
1292
-			run = coeff >> 8;
1293
-			level = coeff & 0xff;
1294
-			if( this.buffer.getBits(1) ) {
1295
-				level = -level;
1296
-			}
1297
-		}
1298
-		
1299
-		n += run;
1300
-		var dezigZagged = ZIG_ZAG[n];
1301
-		n++;
1302
-		
1303
-		// Dequantize, oddify, clip
1304
-		level <<= 1;
1305
-		if( !this.macroblockIntra ) {
1306
-			level += (level < 0 ? -1 : 1);
1307
-		}
1308
-		level = (level * this.quantizerScale * quantMatrix[dezigZagged]) >> 4;
1309
-		if( (level & 1) == 0 ) {
1310
-			level -= level > 0 ? 1 : -1;
1311
-		}
1312
-		if( level > 2047 ) {
1313
-			level = 2047;
1314
-		}
1315
-		else if( level < -2048 ) {
1316
-			level = -2048;
1317
-		}
1207
+  var
1208
+    n = 0,
1209
+    quantMatrix;
1210
+    
1211
+  // Decode DC coefficient of intra-coded blocks
1212
+  if( this.macroblockIntra ) {
1213
+    var 
1214
+      predictor,
1215
+      dctSize;
1216
+    
1217
+    // DC prediction
1218
+    
1219
+    if( block < 4 ) {
1220
+      predictor = this.dcPredictorY;
1221
+      dctSize = this.readCode(DCT_DC_SIZE_LUMINANCE);
1222
+    }
1223
+    else {
1224
+      predictor = (block == 4 ? this.dcPredictorCr : this.dcPredictorCb);
1225
+      dctSize = this.readCode(DCT_DC_SIZE_CHROMINANCE);
1226
+    }
1227
+    
1228
+    // Read DC coeff
1229
+    if( dctSize > 0 ) {
1230
+      var differential = this.buffer.getBits(dctSize);
1231
+      if( (differential & (1 << (dctSize - 1))) != 0 ) {
1232
+        this.blockData[0] = predictor + differential;
1233
+      }
1234
+      else {
1235
+        this.blockData[0] = predictor + ((-1 << dctSize)|(differential+1));
1236
+      }
1237
+    }
1238
+    else {
1239
+      this.blockData[0] = predictor;
1240
+    }
1241
+    
1242
+    // Save predictor value
1243
+    if( block < 4 ) {
1244
+      this.dcPredictorY = this.blockData[0];
1245
+    }
1246
+    else if( block == 4 ) {
1247
+      this.dcPredictorCr = this.blockData[0];
1248
+    }
1249
+    else {
1250
+      this.dcPredictorCb = this.blockData[0];
1251
+    }
1252
+    
1253
+    // Dequantize + premultiply
1254
+    this.blockData[0] <<= (3 + 5);
1255
+    
1256
+    quantMatrix = this.intraQuantMatrix;
1257
+    n = 1;
1258
+  }
1259
+  else {
1260
+    quantMatrix = this.nonIntraQuantMatrix;
1261
+  }
1262
+  
1263
+  // Decode AC coefficients (+DC for non-intra)
1264
+  var level = 0;
1265
+  while( true ) {
1266
+    var 
1267
+      run = 0,
1268
+      coeff = this.readCode(DCT_COEFF);
1269
+    
1270
+    if( (coeff == 0x0001) && (n > 0) && (this.buffer.getBits(1) == 0) ) {
1271
+      // end_of_block
1272
+      break;
1273
+    }
1274
+    if( coeff == 0xffff ) {
1275
+      // escape
1276
+      run = this.buffer.getBits(6);
1277
+      level = this.buffer.getBits(8);
1278
+      if( level == 0 ) {
1279
+        level = this.buffer.getBits(8);
1280
+      }
1281
+      else if( level == 128 ) {
1282
+        level = this.buffer.getBits(8) - 256;
1283
+      }
1284
+      else if( level > 128 ) {
1285
+        level = level - 256;
1286
+      }
1287
+    }
1288
+    else {
1289
+      run = coeff >> 8;
1290
+      level = coeff & 0xff;
1291
+      if( this.buffer.getBits(1) ) {
1292
+        level = -level;
1293
+      }
1294
+    }
1295
+    
1296
+    n += run;
1297
+    var dezigZagged = ZIG_ZAG[n];
1298
+    n++;
1299
+    
1300
+    // Dequantize, oddify, clip
1301
+    level <<= 1;
1302
+    if( !this.macroblockIntra ) {
1303
+      level += (level < 0 ? -1 : 1);
1304
+    }
1305
+    level = (level * this.quantizerScale * quantMatrix[dezigZagged]) >> 4;
1306
+    if( (level & 1) == 0 ) {
1307
+      level -= level > 0 ? 1 : -1;
1308
+    }
1309
+    if( level > 2047 ) {
1310
+      level = 2047;
1311
+    }
1312
+    else if( level < -2048 ) {
1313
+      level = -2048;
1314
+    }
1315
+
1316
+    // Save premultiplied coefficient
1317
+    this.blockData[dezigZagged] = level * PREMULTIPLIER_MATRIX[dezigZagged];
1318
+  };
1319
+  
1320
+  // Move block to its place
1321
+  var
1322
+    destArray,
1323
+    destIndex,
1324
+    scan;
1325
+  
1326
+  if( block < 4 ) {
1327
+    destArray = this.currentY;
1328
+    scan = this.codedWidth - 8;
1329
+    destIndex = (this.mbRow * this.codedWidth + this.mbCol) << 4;
1330
+    if( (block & 1) != 0 ) {
1331
+      destIndex += 8;
1332
+    }
1333
+    if( (block & 2) != 0 ) {
1334
+      destIndex += this.codedWidth << 3;
1335
+    }
1336
+  }
1337
+  else {
1338
+    destArray = (block == 4) ? this.currentCb : this.currentCr;
1339
+    scan = (this.codedWidth >> 1) - 8;
1340
+    destIndex = ((this.mbRow * this.codedWidth) << 2) + (this.mbCol << 3);
1341
+  }
1342
+
1343
+  if( this.macroblockIntra ) {
1344
+    // Overwrite (no prediction)
1345
+    if (n == 1) {
1346
+      this.copyValueToDestination((this.blockData[0] + 128) >> 8, destArray, destIndex, scan);
1347
+      this.blockData[0] = 0;
1348
+    } else {
1349
+      this.IDCT();
1350
+      this.copyBlockToDestination(this.blockData, destArray, destIndex, scan);
1351
+      this.blockData.set(this.zeroBlockData);  
1352
+    }
1353
+  }
1354
+  else {
1355
+    // Add data to the predicted macroblock
1356
+    if (n == 1) {
1357
+      this.addValueToDestination((this.blockData[0] + 128) >> 8, destArray, destIndex, scan);
1358
+      this.blockData[0] = 0;
1359
+    } else {
1360
+      this.IDCT();
1361
+      this.addBlockToDestination(this.blockData, destArray, destIndex, scan);  
1362
+      this.blockData.set(this.zeroBlockData);  
1363
+    }
1364
+  }
1365
+  
1366
+  n = 0;
1367
+};
1318 1368
 
1319
-		// Save premultiplied coefficient
1320
-		this.blockData[dezigZagged] = level * PREMULTIPLIER_MATRIX[dezigZagged];
1321
-	};
1322
-	
1323
-	// Transform block data to the spatial domain
1324
-	if( n == 1 ) {
1325
-		// Only DC coeff., no IDCT needed
1326
-		this.fillArray(this.blockData, (this.blockData[0] + 128) >> 8);
1327
-	}
1328
-	else {
1329
-		this.IDCT();
1330
-	}
1331
-	
1332
-	// Move block to its place
1333
-	var
1334
-		destArray,
1335
-		destIndex,
1336
-		scan;
1337
-	
1338
-	if( block < 4 ) {
1339
-		destArray = this.currentY;
1340
-		scan = this.codedWidth - 8;
1341
-		destIndex = (this.mbRow * this.codedWidth + this.mbCol) << 4;
1342
-		if( (block & 1) != 0 ) {
1343
-			destIndex += 8;
1344
-		}
1345
-		if( (block & 2) != 0 ) {
1346
-			destIndex += this.codedWidth << 3;
1347
-		}
1348
-	}
1349
-	else {
1350
-		destArray = (block == 4) ? this.currentCb : this.currentCr;
1351
-		scan = (this.codedWidth >> 1) - 8;
1352
-		destIndex = ((this.mbRow * this.codedWidth) << 2) + (this.mbCol << 3);
1353
-	}
1354
-	
1355
-	n = 0;
1356
-	
1357
-	var blockData = this.blockData;
1358
-	if( this.macroblockIntra ) {
1359
-		// Overwrite (no prediction)
1360
-		this.copyBlockToDestination(this.blockData, destArray, destIndex, scan);
1361
-	}
1362
-	else {
1363
-		// Add data to the predicted macroblock
1364
-		this.addBlockToDestination(this.blockData, destArray, destIndex, scan);
1365
-	}
1369
+jsmpeg.prototype.copyBlockToDestination = function(_blockData, _destArray, _destIndex, scan) {
1370
+  var blockData = _blockData;
1371
+  var destArray = _destArray;
1372
+  var destIndex = _destIndex;
1373
+
1374
+  for (var n = 0; n < 64; n += 8, destIndex += scan+8) {
1375
+    destArray[destIndex+0] = blockData[n+0];
1376
+    destArray[destIndex+1] = blockData[n+1];
1377
+    destArray[destIndex+2] = blockData[n+2];
1378
+    destArray[destIndex+3] = blockData[n+3];
1379
+    destArray[destIndex+4] = blockData[n+4];
1380
+    destArray[destIndex+5] = blockData[n+5];
1381
+    destArray[destIndex+6] = blockData[n+6];
1382
+    destArray[destIndex+7] = blockData[n+7];
1383
+  }
1366 1384
 };
1367 1385
 
1386
+jsmpeg.prototype.addBlockToDestination = function(_blockData, _destArray, _destIndex, scan) {
1387
+  var blockData = _blockData;
1388
+  var destArray = _destArray;
1389
+  var destIndex = _destIndex;
1390
+
1391
+  for (var n = 0; n < 64; n += 8, destIndex += scan+8) {
1392
+    destArray[destIndex+0] += blockData[n+0];
1393
+    destArray[destIndex+1] += blockData[n+1];
1394
+    destArray[destIndex+2] += blockData[n+2];
1395
+    destArray[destIndex+3] += blockData[n+3];
1396
+    destArray[destIndex+4] += blockData[n+4];
1397
+    destArray[destIndex+5] += blockData[n+5];
1398
+    destArray[destIndex+6] += blockData[n+6];
1399
+    destArray[destIndex+7] += blockData[n+7];
1400
+  }
1401
+};
1368 1402
 
1369
-jsmpeg.prototype.copyBlockToDestination = function(blockData, destArray, destIndex, scan) {
1370
-	var n = 0;
1371
-	while(n < 64) {
1372
-    destArray[destIndex++] = blockData[n++];
1373
-    destArray[destIndex++] = blockData[n++];
1374
-    destArray[destIndex++] = blockData[n++];
1375
-    destArray[destIndex++] = blockData[n++];
1376
-    destArray[destIndex++] = blockData[n++];
1377
-    destArray[destIndex++] = blockData[n++];
1378
-    destArray[destIndex++] = blockData[n++];
1379
-    destArray[destIndex++] = blockData[n++];
1380
-		destIndex += scan;
1381
-	}
1403
+jsmpeg.prototype.copyValueToDestination = function(value, _destArray, _destIndex, scan) {
1404
+  var destArray = _destArray;
1405
+  var destIndex = _destIndex;
1406
+
1407
+  for (var n = 0; n < 64; n += 8, destIndex += scan+8) {
1408
+    destArray[destIndex+0] = value;
1409
+    destArray[destIndex+1] = value;
1410
+    destArray[destIndex+2] = value;
1411
+    destArray[destIndex+3] = value;
1412
+    destArray[destIndex+4] = value;
1413
+    destArray[destIndex+5] = value;
1414
+    destArray[destIndex+6] = value;
1415
+    destArray[destIndex+7] = value;
1416
+  }
1382 1417
 };
1383 1418
 
1384
-jsmpeg.prototype.addBlockToDestination = function(blockData, destArray, destIndex, scan) {
1385
-	var n = 0;
1386
-  while(n < 64) {
1387
-    destArray[destIndex++] += blockData[n++];
1388
-    destArray[destIndex++] += blockData[n++];
1389
-    destArray[destIndex++] += blockData[n++];
1390
-    destArray[destIndex++] += blockData[n++];
1391
-    destArray[destIndex++] += blockData[n++];
1392
-    destArray[destIndex++] += blockData[n++];
1393
-    destArray[destIndex++] += blockData[n++];
1394
-    destArray[destIndex++] += blockData[n++];
1395
-		destIndex += scan;
1396
-	}
1419
+jsmpeg.prototype.addValueToDestination = function(value, _destArray, _destIndex, scan) {
1420
+  var destArray = _destArray;
1421
+  var destIndex = _destIndex;
1422
+
1423
+  for (var n = 0; n < 64; n += 8, destIndex += scan+8) {
1424
+    destArray[destIndex+0] += value;
1425
+    destArray[destIndex+1] += value;
1426
+    destArray[destIndex+2] += value;
1427
+    destArray[destIndex+3] += value;
1428
+    destArray[destIndex+4] += value;
1429
+    destArray[destIndex+5] += value;
1430
+    destArray[destIndex+6] += value;
1431
+    destArray[destIndex+7] += value;
1432
+  }
1397 1433
 };
1398 1434
 
1399 1435
 // Clamping version for shitty browsers (IE) that don't support Uint8ClampedArray