Преглед изворни кода

Removed partial support for B-Frames

Dominic Szablewski пре 12 година
родитељ
комит
22f4a3d9f0
1 измењених фајлова са 14 додато и 263 уклоњено
  1. 14 263
      jsmpg.js

+ 14 - 263
jsmpg.js Прегледај датотеку

234
 	this.forwardCr = new Uint8ClampedArray(this.codedSize >> 2);
234
 	this.forwardCr = new Uint8ClampedArray(this.codedSize >> 2);
235
 	this.forwardCb = new Uint8ClampedArray(this.codedSize >> 2);
235
 	this.forwardCb = new Uint8ClampedArray(this.codedSize >> 2);
236
 	
236
 	
237
-	this.backwardY = new Uint8ClampedArray(this.codedSize);
238
-	this.backwardCr = new Uint8ClampedArray(this.codedSize >> 2);
239
-	this.backwardCb = new Uint8ClampedArray(this.codedSize >> 2);
240
-	
241
 	this.canvas.width = this.width;
237
 	this.canvas.width = this.width;
242
 	this.canvas.height = this.height;
238
 	this.canvas.height = this.height;
243
 	
239
 	
264
 jsmpeg.prototype.forwardCr = null;
260
 jsmpeg.prototype.forwardCr = null;
265
 jsmpeg.prototype.forwardCb = null;
261
 jsmpeg.prototype.forwardCb = null;
266
 
262
 
267
-jsmpeg.prototype.backwardY = null;
268
-jsmpeg.prototype.backwardCr = null;
269
-jsmpeg.prototype.backwardCb = null;
270
-
271
 jsmpeg.prototype.fullPelForward = false;
263
 jsmpeg.prototype.fullPelForward = false;
272
 jsmpeg.prototype.forwardFCode = 0;
264
 jsmpeg.prototype.forwardFCode = 0;
273
 jsmpeg.prototype.forwardRSize = 0;
265
 jsmpeg.prototype.forwardRSize = 0;
274
 jsmpeg.prototype.forwardF = 0;
266
 jsmpeg.prototype.forwardF = 0;
275
 
267
 
276
-jsmpeg.prototype.fullPelBackward = false;
277
-jsmpeg.prototype.backwardFCode = 0;
278
-jsmpeg.prototype.backwardRSize = 0;
279
-jsmpeg.prototype.backwardF = 0;
280
-
281
 
268
 
282
 jsmpeg.prototype.decodePicture = function() {	
269
 jsmpeg.prototype.decodePicture = function() {	
283
 	this.buffer.advance(10); // skip temporalReference
270
 	this.buffer.advance(10); // skip temporalReference
303
 	
290
 	
304
 	// full_pel_backward, backward_f_code
291
 	// full_pel_backward, backward_f_code
305
 	if( this.pictureCodingType == PICTURE_TYPE_B ) {
292
 	if( this.pictureCodingType == PICTURE_TYPE_B ) {
306
-		this.fullPelBackward = this.buffer.getBits(1);
307
-		this.backwardFCode = this.buffer.getBits(3);
308
-		if( this.backwardFCode == 0 ) {
309
-			// Ignore picture with zero backward_f_code
310
-			return;
311
-		}
312
-		this.backwardRSize = this.backwardFCode - 1;
313
-		this.backwardF = 1 << this.backwardRSize;
314
-	}
315
-	
316
-	var 
317
-		tmpY = this.forwardY,
318
-		tmpCr = this.forwardCr,
319
-		tmpCb = this.forwardCb;
320
-
321
-	if( this.pictureCodingType == PICTURE_TYPE_I || this.pictureCodingType == PICTURE_TYPE_P ) {
322
-		this.forwardY = this.backwardY;
323
-		this.forwardCr = this.backwardCr;
324
-		this.forwardCb = this.backwardCb;
293
+		// We can't deal with B frames
294
+		return;
325
 	}
295
 	}
326
 	
296
 	
327
 	var code = 0;
297
 	var code = 0;
344
 	
314
 	
345
 	// If this is a reference picutre then rotate the prediction pointers
315
 	// If this is a reference picutre then rotate the prediction pointers
346
 	if( this.pictureCodingType == PICTURE_TYPE_I || this.pictureCodingType == PICTURE_TYPE_P ) {
316
 	if( this.pictureCodingType == PICTURE_TYPE_I || this.pictureCodingType == PICTURE_TYPE_P ) {
347
-		this.backwardY = this.currentY;
348
-		this.backwardCr = this.currentCr;
349
-		this.backwardCb = this.currentCb;
317
+		var 
318
+			tmpY = this.forwardY,
319
+			tmpCr = this.forwardCr,
320
+			tmpCb = this.forwardCb;
321
+
322
+		this.forwardY = this.currentY;
323
+		this.forwardCr = this.currentCr;
324
+		this.forwardCb = this.currentCb;
325
+
350
 		this.currentY = tmpY;
326
 		this.currentY = tmpY;
351
 		this.currentCr = tmpCr;
327
 		this.currentCr = tmpCr;
352
 		this.currentCb = tmpCb;
328
 		this.currentCb = tmpCb;
440
 	// Reset motion vectors and DC predictors
416
 	// Reset motion vectors and DC predictors
441
 	this.motionFwH = this.motionFwHPrev = 0;
417
 	this.motionFwH = this.motionFwHPrev = 0;
442
 	this.motionFwV = this.motionFwVPrev = 0;
418
 	this.motionFwV = this.motionFwVPrev = 0;
443
-	this.motionBwH = this.motionBwHPrev = 0;
444
-	this.motionBwV = this.motionBwVPrev = 0;
445
 	this.dcPredictorY  = 128;
419
 	this.dcPredictorY  = 128;
446
 	this.dcPredictorCr = 128;
420
 	this.dcPredictorCr = 128;
447
 	this.dcPredictorCb = 128;
421
 	this.dcPredictorCb = 128;
470
 jsmpeg.prototype.macroblockType = 0;
444
 jsmpeg.prototype.macroblockType = 0;
471
 jsmpeg.prototype.macroblockIntra = false;
445
 jsmpeg.prototype.macroblockIntra = false;
472
 jsmpeg.prototype.macroblockMotFw = false;
446
 jsmpeg.prototype.macroblockMotFw = false;
473
-jsmpeg.prototype.macroblockMotBw = false;
474
 	
447
 	
475
 jsmpeg.prototype.motionFwH = 0;
448
 jsmpeg.prototype.motionFwH = 0;
476
 jsmpeg.prototype.motionFwV = 0;
449
 jsmpeg.prototype.motionFwV = 0;
477
-jsmpeg.prototype.motionBwH = 0;
478
-jsmpeg.prototype.motionBwV = 0;
479
 jsmpeg.prototype.motionFwHPrev = 0;
450
 jsmpeg.prototype.motionFwHPrev = 0;
480
 jsmpeg.prototype.motionFwVPrev = 0;
451
 jsmpeg.prototype.motionFwVPrev = 0;
481
-jsmpeg.prototype.motionBwHPrev = 0;
482
-jsmpeg.prototype.motionBwVPrev = 0;
483
 
452
 
484
 jsmpeg.prototype.decodeMacroblock = function() {
453
 jsmpeg.prototype.decodeMacroblock = function() {
485
 	// Decode macroblock_address_increment
454
 	// Decode macroblock_address_increment
528
 			this.macroblockAddress++;
497
 			this.macroblockAddress++;
529
 			this.mbRow = (this.macroblockAddress / this.mbWidth)|0;
498
 			this.mbRow = (this.macroblockAddress / this.mbWidth)|0;
530
 			this.mbCol = this.macroblockAddress % this.mbWidth;
499
 			this.mbCol = this.macroblockAddress % this.mbWidth;
531
-			this.predictMacroblock();
500
+			this.copyMacroblock(this.motionFwH, this.motionFwV, this.forwardY, this.forwardCr, this.forwardCb);
532
 			increment--;
501
 			increment--;
533
 		}
502
 		}
534
 		this.macroblockAddress++;
503
 		this.macroblockAddress++;
540
 	this.macroblockType = this.readCode(MACROBLOCK_TYPE_TABLES[this.pictureCodingType]);
509
 	this.macroblockType = this.readCode(MACROBLOCK_TYPE_TABLES[this.pictureCodingType]);
541
 	this.macroblockIntra = (this.macroblockType & 0x01);
510
 	this.macroblockIntra = (this.macroblockType & 0x01);
542
 	this.macroblockMotFw = (this.macroblockType & 0x08);
511
 	this.macroblockMotFw = (this.macroblockType & 0x08);
543
-	this.macroblockMotBw = (this.macroblockType & 0x04);
544
 
512
 
545
 	// Quantizer scale
513
 	// Quantizer scale
546
 	if( (this.macroblockType & 0x10) != 0 ) {
514
 	if( (this.macroblockType & 0x10) != 0 ) {
551
 		// Intra-coded macroblocks reset motion vectors
519
 		// Intra-coded macroblocks reset motion vectors
552
 		this.motionFwH = this.motionFwHPrev = 0;
520
 		this.motionFwH = this.motionFwHPrev = 0;
553
 		this.motionFwV = this.motionFwVPrev = 0;
521
 		this.motionFwV = this.motionFwVPrev = 0;
554
-		this.motionBwH = this.motionBwHPrev = 0;
555
-		this.motionBwV = this.motionBwVPrev = 0;
556
 	}
522
 	}
557
 	else {
523
 	else {
558
 		// Non-intra macroblocks reset DC predictors
524
 		// Non-intra macroblocks reset DC predictors
561
 		this.dcPredictorCb = 128;
527
 		this.dcPredictorCb = 128;
562
 		
528
 		
563
 		this.decodeMotionVectors();
529
 		this.decodeMotionVectors();
564
-		this.predictMacroblock();
530
+		this.copyMacroblock(this.motionFwH, this.motionFwV, this.forwardY, this.forwardCr, this.forwardCb);
565
 	}
531
 	}
566
 
532
 
567
 	// Decode blocks
533
 	// Decode blocks
640
 		this.motionFwH = this.motionFwHPrev = 0;
606
 		this.motionFwH = this.motionFwHPrev = 0;
641
 		this.motionFwV = this.motionFwVPrev = 0;
607
 		this.motionFwV = this.motionFwVPrev = 0;
642
 	}
608
 	}
643
-	
644
-	
645
-	// Backward
646
-	if( this.macroblockMotBw ) {
647
-		// Horizontal backward
648
-		code = this.readCode(MOTION);
649
-		if( (code != 0) && (this.backwardF != 1) ) {
650
-			r = this.buffer.getBits(this.backwardRSize);
651
-			d = ((Math.abs(code) - 1) << this.backwardRSize) + r + 1;
652
-			if( code < 0 ) {
653
-				d = -d;
654
-			}
655
-		}
656
-		else {
657
-			d = code;
658
-		}
659
-		
660
-		this.motionBwHPrev += d;
661
-		if( this.motionBwHPrev > (this.backwardF << 4) - 1 ) {
662
-			this.motionBwHPrev -= this.backwardF << 5;
663
-		}
664
-		else if( this.motionBwHPrev < ((-this.backwardF) << 4) ) {
665
-			this.motionBwHPrev += this.backwardF << 5;
666
-		}
667
-		
668
-		this.motionBwH = this.motionBwHPrev;
669
-		if( this.fullPelForward ) {
670
-			this.motionBwH <<= 1;
671
-		}
672
-		
673
-		// Vertical backward
674
-		code = this.readCode(MOTION);
675
-		if ((code != 0) && (this.backwardF != 1)) {
676
-			r = this.buffer.getBits(this.backwardRSize);
677
-			d = ((Math.abs(code) - 1) << this.backwardRSize) + r + 1;
678
-			if( code < 0 ) {
679
-				d = -d;
680
-			}
681
-		}
682
-		else {
683
-			d = code;
684
-		}
685
-		
686
-		this.motionBwVPrev += d;
687
-		if( this.motionBwVPrev > (this.backwardF << 4) - 1 ) {
688
-			this.motionBwVPrev -= this.backwardF << 5;
689
-		}
690
-		else if( this.motionBwVPrev < ((-this.backwardF) << 4)) {
691
-			this.motionBwVPrev += this.backwardF << 5;
692
-		}
693
-		
694
-		this.motionBwV = this.motionBwVPrev;
695
-		if( this.fullPelForward ) {
696
-			this.motionBwV <<= 1;
697
-		}
698
-		
699
-		this.motionBwV= this.motionBwVPrev;
700
-		if( this.fullPelBackward ) {
701
-			this.motionBwVPrev <<= 1;
702
-		}
703
-	}
704
 };
609
 };
705
 
610
 
706
 jsmpeg.prototype.copyMacroblock = function(motionH, motionV, sY, sCr, sCb ) {
611
 jsmpeg.prototype.copyMacroblock = function(motionH, motionV, sY, sCr, sCb ) {
708
 		width, scan, 
613
 		width, scan, 
709
 		H, V, oddH, oddV,
614
 		H, V, oddH, oddV,
710
 		src, dest, last;
615
 		src, dest, last;
711
-	
616
+
712
 	var dY = this.currentY;
617
 	var dY = this.currentY;
713
 	var dCb = this.currentCb;
618
 	var dCb = this.currentCb;
714
 	var dCr = this.currentCr;
619
 	var dCr = this.currentCr;
830
 };
735
 };
831
 
736
 
832
 
737
 
833
-jsmpeg.prototype.interpolateMacroblock = function() {
834
-	var 
835
-		width, scan, 
836
-		H, V, oddH, oddV,
837
-		src, dest, last;
838
-	
839
-	// Luminance
840
-	width = this.codedWidth;
841
-	scan = width - 16;
842
-	
843
-	H = this.motionBwH >> 1;
844
-	V = this.motionBwV >> 1;
845
-	oddH = (this.motionBwH & 1) == 1;
846
-	oddV = (this.motionBwV & 1) == 1;
847
-	
848
-	src  = ((this.mbRow << 4) + V) * width + (this.mbCol << 4) + H;
849
-	dest = (this.mbRow * width + this.mbCol) << 4;
850
-	last = dest + (width << 4);
851
-	
852
-	if( oddH ) {
853
-		if( oddV ) {
854
-			while( dest < last ) {
855
-				for( var x = 0; x < 16; x++ ) {
856
-					this.currentY[dest] += ((this.backwardY[src] + this.backwardY[src+1] +
857
-						this.backwardY[src+width] + this.backwardY[src+width+1] + 2) >> 2) + 1;
858
-					this.currentY[dest] >>= 1;
859
-					dest++; src++;
860
-				}
861
-				dest += scan; src += scan;
862
-			}
863
-		}
864
-		else {
865
-			while( dest < last ) {
866
-				for( var x = 0; x < 16; x++ ) {
867
-					this.currentY[dest] += ((this.backwardY[src] + this.backwardY[src+1] + 1) >> 1) + 1;
868
-					this.currentY[dest] >>= 1;
869
-					dest++; src++;
870
-				}
871
-				dest += scan; src += scan;
872
-			}
873
-		}
874
-	}
875
-	else {
876
-		if( oddV ) {
877
-			while( dest < last ) {
878
-				for( var x = 0; x < 16; x++ ) {
879
-					this.currentY[dest] += ((this.backwardY[src] + this.backwardY[src+width] + 1) >> 1) + 1;
880
-					this.currentY[dest] >>= 1;
881
-					dest++; src++;
882
-				}
883
-				dest += scan; src += scan;
884
-			}
885
-		}
886
-		else {
887
-			while( dest < last ) {
888
-				for( var x = 0; x < 16; x++ ) {
889
-					this.currentY[dest] += this.backwardY[src] + 1;
890
-					this.currentY[dest] >>= 1;
891
-					dest++; src++;
892
-				}
893
-				dest += scan; src += scan;
894
-			}
895
-		}
896
-	}
897
-	
898
-	// Chrominance
899
-	width = this.halfWidth;
900
-	scan = width - 8;
901
-	
902
-	H = (this.motionBwH/2) >> 1;
903
-	V = (this.motionBwV/2) >> 1;
904
-	oddH = ((this.motionBwH/2) & 1) == 1;
905
-	oddV = ((this.motionBwV/2) & 1) == 1;
906
-	
907
-	src = ((this.mbRow << 3) + V) * width + (this.mbCol << 3) + H;
908
-	dest = (this.mbRow * width + this.mbCol) << 3;
909
-	last = dest + (width << 3);
910
-	
911
-	if( oddH ) {
912
-		if( oddV ) {
913
-			while( dest < last ) {
914
-				for( var x = 0; x < 8; x++ ) {
915
-					this.currentCr[dest] += ((this.backwardCr[src] + this.backwardCr[src+1] +
916
-						this.backwardCr[src+width] + this.backwardCr[src+width+1] + 2) >> 2) + 1;
917
-					this.currentCb[dest] += ((this.backwardCb[src] + this.backwardCb[src+1] +
918
-						this.backwardCb[src+width] + this.backwardCb[src+width+1] + 2) >> 2) + 1;
919
-					this.currentCr[dest] >>= 1;
920
-					this.currentCb[dest] >>= 1;
921
-					dest++; src++;
922
-				}
923
-				dest += scan; src += scan;
924
-			}
925
-		}
926
-		else {
927
-			while( dest < last ) {
928
-				for( var x = 0; x < 8; x++ ) {
929
-					this.currentCr[dest] += ((this.backwardCr[src] + this.backwardCr[src+1] + 1) >> 1) + 1;
930
-					this.currentCb[dest] += ((this.backwardCb[src] + this.backwardCb[src+1] + 1) >> 1) + 1;
931
-					this.currentCr[dest] >>= 1;
932
-					this.currentCb[dest] >>= 1;
933
-					dest++; src++;
934
-				}
935
-				dest += scan; src += scan;
936
-			}
937
-		}
938
-	}
939
-	else {
940
-		if( oddV ) {
941
-			while( dest < last ) {
942
-				for( var x = 0; x < 8; x++ ) {
943
-					this.currentCr[dest] += ((this.backwardCr[src] + this.backwardCr[src+width] + 1) >> 1) + 1;
944
-					this.currentCb[dest] += ((this.backwardCb[src] + this.backwardCb[src+width] + 1) >> 1) + 1;
945
-					this.currentCr[dest] >>= 1;
946
-					this.currentCb[dest] >>= 1;
947
-					dest++; src++;
948
-				}
949
-				dest += scan; src += scan;
950
-			}
951
-		}
952
-		else {
953
-			while( dest < last ) {
954
-				for( var x = 0; x < 8; x++ ) {
955
-					this.currentCr[dest] += this.backwardCr[src] + 1;
956
-					this.currentCb[dest] += this.backwardCb[src] + 1;
957
-					this.currentCr[dest] >>= 1;
958
-					this.currentCb[dest] >>= 1;
959
-					dest++; src++;
960
-				}
961
-				dest += scan; src += scan;
962
-			}
963
-		}
964
-	}
965
-};
966
-
967
-jsmpeg.prototype.predictMacroblock = function() {
968
-	if( this.pictureCodingType == PICTURE_TYPE_B ) {
969
-		if( this.macroblockMotFw ) {
970
-			this.copyMacroblock(this.motionFwH, this.motionFwV, this.forwardY, this.forwardCr, this.forwardCb);
971
-			if( this.macroblockMotBw ) {
972
-				this.interpolateMacroblock();
973
-			}
974
-		}
975
-		else {
976
-			this.copyMacroblock(this.motionBwH, this.motionBwV, this.backwardY, this.backwardCr, this.backwardCb);
977
-		}
978
-	}
979
-	else {
980
-		this.copyMacroblock(this.motionFwH, this.motionFwV, this.forwardY, this.forwardCr, this.forwardCb);
981
-	}
982
-	// Ignore error on motion vectors pointing outside the bitmap
983
-};
984
-
985
-
986
-
987
 // ----------------------------------------------------------------------------
738
 // ----------------------------------------------------------------------------
988
 // Block layer
739
 // Block layer
989
 
740