|
|
@@ -38,6 +38,8 @@ var jsmpeg = window.jsmpeg = function( url, opts ) {
|
|
38
|
38
|
this.customIntraQuantMatrix = new Uint8Array(64);
|
|
39
|
39
|
this.customNonIntraQuantMatrix = new Uint8Array(64);
|
|
40
|
40
|
this.blockData = new Int32Array(64);
|
|
|
41
|
+ this.zeroBlockData = new Int32Array(64);
|
|
|
42
|
+ this.fillArray(this.zeroBlockData, 0);
|
|
41
|
43
|
|
|
42
|
44
|
this.canvasContext = this.canvas.getContext('2d');
|
|
43
|
45
|
|
|
|
@@ -693,30 +695,26 @@ jsmpeg.prototype.YCbCrToRGBA = function() {
|
|
693
|
695
|
b = (cb + ((cb * 198) >> 8)) - 227;
|
|
694
|
696
|
|
|
695
|
697
|
// Line 1
|
|
696
|
|
- y = pY[yIndex1++];
|
|
697
|
|
- pRGBA[rgbaIndex1] = y + r;
|
|
698
|
|
- pRGBA[rgbaIndex1+1] = y - g;
|
|
699
|
|
- pRGBA[rgbaIndex1+2] = y + b;
|
|
700
|
|
- rgbaIndex1 += 4;
|
|
701
|
|
-
|
|
702
|
|
- y = pY[yIndex1++];
|
|
703
|
|
- pRGBA[rgbaIndex1] = y + r;
|
|
704
|
|
- pRGBA[rgbaIndex1+1] = y - g;
|
|
705
|
|
- pRGBA[rgbaIndex1+2] = y + b;
|
|
706
|
|
- rgbaIndex1 += 4;
|
|
707
|
|
-
|
|
|
698
|
+ var y1 = pY[yIndex1++];
|
|
|
699
|
+ var y2 = pY[yIndex1++];
|
|
|
700
|
+ pRGBA[rgbaIndex1] = y1 + r;
|
|
|
701
|
+ pRGBA[rgbaIndex1+1] = y1 - g;
|
|
|
702
|
+ pRGBA[rgbaIndex1+2] = y1 + b;
|
|
|
703
|
+ pRGBA[rgbaIndex1+4] = y2 + r;
|
|
|
704
|
+ pRGBA[rgbaIndex1+5] = y2 - g;
|
|
|
705
|
+ pRGBA[rgbaIndex1+6] = y2 + b;
|
|
|
706
|
+ rgbaIndex1 += 8;
|
|
|
707
|
+
|
|
708
|
708
|
// Line 2
|
|
709
|
|
- y = pY[yIndex2++];
|
|
710
|
|
- pRGBA[rgbaIndex2] = y + r;
|
|
711
|
|
- pRGBA[rgbaIndex2+1] = y - g;
|
|
712
|
|
- pRGBA[rgbaIndex2+2] = y + b;
|
|
713
|
|
- rgbaIndex2 += 4;
|
|
714
|
|
-
|
|
715
|
|
- y = pY[yIndex2++];
|
|
716
|
|
- pRGBA[rgbaIndex2] = y + r;
|
|
717
|
|
- pRGBA[rgbaIndex2+1] = y - g;
|
|
718
|
|
- pRGBA[rgbaIndex2+2] = y + b;
|
|
719
|
|
- rgbaIndex2 += 4;
|
|
|
709
|
+ var y3 = pY[yIndex2++];
|
|
|
710
|
+ var y4 = pY[yIndex2++];
|
|
|
711
|
+ pRGBA[rgbaIndex2] = y3 + r;
|
|
|
712
|
+ pRGBA[rgbaIndex2+1] = y3 - g;
|
|
|
713
|
+ pRGBA[rgbaIndex2+2] = y3 + b;
|
|
|
714
|
+ pRGBA[rgbaIndex2+4] = y4 + r;
|
|
|
715
|
+ pRGBA[rgbaIndex2+5] = y4 - g;
|
|
|
716
|
+ pRGBA[rgbaIndex2+6] = y4 + b;
|
|
|
717
|
+ rgbaIndex2 += 8;
|
|
720
|
718
|
}
|
|
721
|
719
|
|
|
722
|
720
|
yIndex1 += yNext2Lines;
|
|
|
@@ -1209,10 +1207,7 @@ jsmpeg.prototype.decodeBlock = function(block) {
|
|
1209
|
1207
|
var
|
|
1210
|
1208
|
n = 0,
|
|
1211
|
1209
|
quantMatrix;
|
|
1212
|
|
-
|
|
1213
|
|
- // Clear preverious data
|
|
1214
|
|
- this.fillArray(this.blockData, 0);
|
|
1215
|
|
-
|
|
|
1210
|
+
|
|
1216
|
1211
|
// Decode DC coefficient of intra-coded blocks
|
|
1217
|
1212
|
if( this.macroblockIntra ) {
|
|
1218
|
1213
|
var
|
|
|
@@ -1322,15 +1317,6 @@ jsmpeg.prototype.decodeBlock = function(block) {
|
|
1322
|
1317
|
this.blockData[dezigZagged] = level * PREMULTIPLIER_MATRIX[dezigZagged];
|
|
1323
|
1318
|
};
|
|
1324
|
1319
|
|
|
1325
|
|
- // Transform block data to the spatial domain
|
|
1326
|
|
- if( n == 1 ) {
|
|
1327
|
|
- // Only DC coeff., no IDCT needed
|
|
1328
|
|
- this.fillArray(this.blockData, (this.blockData[0] + 128) >> 8);
|
|
1329
|
|
- }
|
|
1330
|
|
- else {
|
|
1331
|
|
- this.IDCT();
|
|
1332
|
|
- }
|
|
1333
|
|
-
|
|
1334
|
1320
|
// Move block to its place
|
|
1335
|
1321
|
var
|
|
1336
|
1322
|
destArray,
|
|
|
@@ -1353,38 +1339,96 @@ jsmpeg.prototype.decodeBlock = function(block) {
|
|
1353
|
1339
|
scan = (this.codedWidth >> 1) - 8;
|
|
1354
|
1340
|
destIndex = ((this.mbRow * this.codedWidth) << 2) + (this.mbCol << 3);
|
|
1355
|
1341
|
}
|
|
1356
|
|
-
|
|
1357
|
|
- n = 0;
|
|
1358
|
|
-
|
|
1359
|
|
- var blockData = this.blockData;
|
|
|
1342
|
+
|
|
1360
|
1343
|
if( this.macroblockIntra ) {
|
|
1361
|
1344
|
// Overwrite (no prediction)
|
|
1362
|
|
- this.copyBlockToDestination(this.blockData, destArray, destIndex, scan);
|
|
|
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
|
+ }
|
|
1363
|
1353
|
}
|
|
1364
|
1354
|
else {
|
|
1365
|
1355
|
// Add data to the predicted macroblock
|
|
1366
|
|
- this.addBlockToDestination(this.blockData, destArray, destIndex, scan);
|
|
|
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
|
+ }
|
|
1367
|
1364
|
}
|
|
|
1365
|
+
|
|
|
1366
|
+ n = 0;
|
|
1368
|
1367
|
};
|
|
1369
|
1368
|
|
|
|
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
|
+ }
|
|
|
1384
|
+};
|
|
1370
|
1385
|
|
|
1371
|
|
-jsmpeg.prototype.copyBlockToDestination = function(blockData, destArray, destIndex, scan) {
|
|
1372
|
|
- var n = 0;
|
|
1373
|
|
- for( var i = 0; i < 8; i++ ) {
|
|
1374
|
|
- for( var j = 0; j < 8; j++ ) {
|
|
1375
|
|
- destArray[destIndex++] = blockData[n++];
|
|
1376
|
|
- }
|
|
1377
|
|
- destIndex += scan;
|
|
|
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];
|
|
1378
|
1400
|
}
|
|
1379
|
1401
|
};
|
|
1380
|
1402
|
|
|
1381
|
|
-jsmpeg.prototype.addBlockToDestination = function(blockData, destArray, destIndex, scan) {
|
|
1382
|
|
- var n = 0;
|
|
1383
|
|
- for( var i = 0; i < 8; i++ ) {
|
|
1384
|
|
- for( var j = 0; j < 8; j++ ) {
|
|
1385
|
|
- destArray[destIndex++] += blockData[n++];
|
|
1386
|
|
- }
|
|
1387
|
|
- destIndex += scan;
|
|
|
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
|
+ }
|
|
|
1417
|
+};
|
|
|
1418
|
+
|
|
|
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;
|
|
1388
|
1432
|
}
|
|
1389
|
1433
|
};
|
|
1390
|
1434
|
|