1576 lines
50 KiB
JavaScript
1576 lines
50 KiB
JavaScript
var AMT = {
|
|
Player: null,
|
|
BitBuffer: null,
|
|
Source: {},
|
|
Demuxer: {},
|
|
Decoder: {},
|
|
Renderer: {},
|
|
Now: function() {
|
|
return window.performance ? window.performance.now() / 1e3 : Date.now() / 1e3
|
|
},
|
|
Fill: function(t, e) {
|
|
if (t.fill) {
|
|
t.fill(e)
|
|
} else {
|
|
for (var i = 0; i < t.length; i++) {
|
|
t[i] = e
|
|
}
|
|
}
|
|
}
|
|
};
|
|
AMT.Source.WebSocket = function() {
|
|
"use strict";
|
|
var t = function(t, e) {
|
|
this.url = t;
|
|
this.options = e;
|
|
this.socket = null;
|
|
this.callbacks = {
|
|
connect: [],
|
|
data: []
|
|
};
|
|
this.destination = null;
|
|
this.reconnectInterval = e.reconnectInterval !== undefined ? e.reconnectInterval : 5;
|
|
this.shouldAttemptReconnect = !! this.reconnectInterval;
|
|
this.completed = false;
|
|
this.established = false;
|
|
this.progress = 0;
|
|
this.reconnectTimeoutId = 0
|
|
};
|
|
t.prototype.connect = function(t) {
|
|
this.destination = t
|
|
};
|
|
t.prototype.destroy = function() {
|
|
clearTimeout(this.reconnectTimeoutId);
|
|
this.shouldAttemptReconnect = false;
|
|
this.socket.close()
|
|
};
|
|
t.prototype.start = function() {
|
|
this.shouldAttemptReconnect = !! this.reconnectInterval;
|
|
this.progress = 0;
|
|
this.established = false;
|
|
this.socket = new WebSocket(this.url, this.options.protocols || null);
|
|
this.socket.binaryType = "arraybuffer";
|
|
this.socket.onmessage = this.onMessage.bind(this);
|
|
this.socket.onopen = this.onOpen.bind(this);
|
|
this.socket.onerror = this.onClose.bind(this);
|
|
this.socket.onclose = this.onClose.bind(this)
|
|
};
|
|
t.prototype.resume = function(t) {};
|
|
t.prototype.onOpen = function() {
|
|
this.progress = 1;
|
|
this.established = true;
|
|
this.socket.send("bl|" + this.options.vlab)
|
|
};
|
|
t.prototype.send = function(t) {
|
|
if (this.progress == 1) {
|
|
this.socket.send(t)
|
|
}
|
|
};
|
|
t.prototype.onClose = function() {
|
|
|
|
if (this.shouldAttemptReconnect) {
|
|
clearTimeout(this.reconnectTimeoutId);
|
|
this.reconnectTimeoutId = setTimeout(function() {
|
|
this.start()
|
|
}.bind(this), this.reconnectInterval * 1e3)
|
|
}
|
|
};
|
|
t.prototype.onMessage = function(t) {
|
|
if (this.destination) {
|
|
this.destination.write(t.data)
|
|
}
|
|
};
|
|
return t
|
|
}();
|
|
AMT.Player = function() {
|
|
|
|
"use strict";
|
|
var t = function(t, e) {
|
|
this.options = e || {};
|
|
if (e.source) {
|
|
this.source = new e.source(t, e);
|
|
e.streaming = !! this.source.streaming
|
|
} else if (t.match(/^ws?:\/\//)) {
|
|
this.source = new AMT.Source.WebSocket(t, e);
|
|
e.streaming = true
|
|
}
|
|
this.maxAudioLag = e.maxAudioLag || .25;
|
|
this.loop = e.loop !== false;
|
|
this.autoplay = !! e.autoplay || e.streaming;
|
|
this.demuxer = new AMT.Demuxer.TS(e);
|
|
this.source.connect(this.demuxer);
|
|
if (e.video !== false) {
|
|
this.video = new AMT.Decoder.MPEG1Video(e);
|
|
this.renderer = !e.disableGl && AMT.Renderer.WebGL.IsSupported() ? new AMT.Renderer.WebGL(e) : new AMT.Renderer.Canvas2D(e);
|
|
this.demuxer.connect(AMT.Demuxer.TS.STREAM.VIDEO_1, this.video);
|
|
this.video.connect(this.renderer)
|
|
}
|
|
Object.defineProperty(this, "currentTime", {
|
|
get: this.getCurrentTime,
|
|
set: this.setCurrentTime
|
|
});
|
|
this.unpauseOnShow = false;
|
|
if (e.pauseWhenHidden !== false) {
|
|
document.addEventListener("visibilitychange", this.showHide.bind(this))
|
|
}
|
|
this.source.start();
|
|
if (this.autoplay) {
|
|
this.play()
|
|
}
|
|
};
|
|
t.prototype.playerVName = function(t) {
|
|
this.source.send("bl|" + t)
|
|
};
|
|
t.prototype.showHide = function(t) {
|
|
if (document.visibilityState === "hidden") {
|
|
this.unpauseOnShow = this.wantsToPlay;
|
|
this.pause()
|
|
} else if (this.unpauseOnShow) {
|
|
this.play()
|
|
}
|
|
};
|
|
t.prototype.play = function(t) {
|
|
this.animationId = requestAnimationFrame(this.update.bind(this));
|
|
this.wantsToPlay = true
|
|
};
|
|
t.prototype.pause = function(t) {
|
|
cancelAnimationFrame(this.animationId);
|
|
this.wantsToPlay = false;
|
|
this.isPlaying = false
|
|
};
|
|
t.prototype.stop = function(t) {
|
|
this.pause();
|
|
this.seek(0);
|
|
if (this.video && this.options.decodeFirstFrame !== false) {
|
|
this.video.decode()
|
|
}
|
|
};
|
|
t.prototype.destroy = function() {
|
|
this.pause();
|
|
this.source.destroy();
|
|
this.renderer.destroy()
|
|
};
|
|
t.prototype.seek = function(t) {
|
|
var e = this.audio && this.audio.canPlay ? this.audio.startTime : this.video.startTime;
|
|
if (this.video) {
|
|
this.video.seek(t + e)
|
|
}
|
|
this.startTime = AMT.Now() - t
|
|
};
|
|
t.prototype.getCurrentTime = function() {
|
|
return this.video.currentTime - this.video.startTime
|
|
};
|
|
t.prototype.setCurrentTime = function(t) {
|
|
this.seek(t)
|
|
};
|
|
t.prototype.update = function() {
|
|
this.animationId = requestAnimationFrame(this.update.bind(this));
|
|
if (!this.source.established) {
|
|
if (this.renderer) {
|
|
this.renderer.renderProgress(this.source.progress)
|
|
}
|
|
return
|
|
}
|
|
if (!this.isPlaying) {
|
|
this.isPlaying = true;
|
|
this.startTime = AMT.Now() - this.currentTime
|
|
}
|
|
if (this.options.streaming) {
|
|
this.updateForStreaming()
|
|
} else {
|
|
this.updateForStaticFile()
|
|
}
|
|
};
|
|
t.prototype.updateForStreaming = function() {
|
|
if (this.video) {
|
|
this.video.decode()
|
|
}
|
|
};
|
|
t.prototype.updateForStaticFile = function() {
|
|
var t = false,
|
|
e = 0;
|
|
if (this.video) {
|
|
var i = AMT.Now() - this.startTime + this.video.startTime,
|
|
r = i - this.video.currentTime,
|
|
s = 1 / this.video.frameRate;
|
|
if (this.video && r > 0) {
|
|
if (r > s * 2) {
|
|
this.startTime += r
|
|
}
|
|
t = !this.video.decode()
|
|
}
|
|
e = this.demuxer.currentTime - i
|
|
}
|
|
this.source.resume(e);
|
|
if (t && this.source.completed) {
|
|
if (this.loop) {
|
|
this.seek(0)
|
|
} else {
|
|
this.pause()
|
|
}
|
|
}
|
|
};
|
|
return t
|
|
}();
|
|
AMT.BitBuffer = function() {
|
|
"use strict";
|
|
var t = function(e, i) {
|
|
if (typeof e === "object") {
|
|
this.bytes = e instanceof Uint8Array ? e : new Uint8Array(e);
|
|
this.byteLength = this.bytes.length
|
|
} else {
|
|
this.bytes = new Uint8Array(e || 1024 * 1024);
|
|
this.byteLength = 0
|
|
}
|
|
this.mode = i || t.MODE.EXPAND;
|
|
this.index = 0
|
|
};
|
|
t.prototype.resize = function(t) {
|
|
var e = new Uint8Array(t);
|
|
if (this.byteLength !== 0) {
|
|
this.byteLength = Math.min(this.byteLength, t);
|
|
e.set(this.bytes, 0, this.byteLength)
|
|
}
|
|
this.bytes = e;
|
|
this.index = Math.min(this.index, this.byteLength << 3)
|
|
};
|
|
t.prototype.evict = function(t) {
|
|
var e = this.index >> 3,
|
|
i = this.bytes.length - this.byteLength;
|
|
if (this.index === this.byteLength << 3 || t > i + e) {
|
|
this.byteLength = 0;
|
|
this.index = 0;
|
|
return
|
|
} else if (e === 0) {
|
|
return
|
|
}
|
|
if (this.bytes.copyWithin) {
|
|
this.bytes.copyWithin(0, e, this.byteLength)
|
|
} else {
|
|
this.bytes.set(this.bytes.subarray(e, this.byteLength))
|
|
}
|
|
this.byteLength = this.byteLength - e;
|
|
this.index -= e << 3;
|
|
return
|
|
};
|
|
t.prototype.write = function(e) {
|
|
var i = typeof e[0] === "object",
|
|
r = 0,
|
|
s = this.bytes.length - this.byteLength;
|
|
if (i) {
|
|
var r = 0;
|
|
for (var o = 0; o < e.length; o++) {
|
|
r += e[o].byteLength
|
|
}
|
|
} else {
|
|
r = e.byteLength
|
|
}
|
|
if (r > s) {
|
|
if (this.mode === t.MODE.EXPAND) {
|
|
var h = Math.max(this.bytes.length * 2, r - s);
|
|
this.resize(h)
|
|
} else {
|
|
this.evict(r)
|
|
}
|
|
}
|
|
if (i) {
|
|
for (var o = 0; o < e.length; o++) {
|
|
this.appendSingleBuffer(e[o])
|
|
}
|
|
} else {
|
|
this.appendSingleBuffer(e)
|
|
}
|
|
};
|
|
t.prototype.appendSingleBuffer = function(t) {
|
|
t = t instanceof Uint8Array ? t : new Uint8Array(t);
|
|
this.bytes.set(t, this.byteLength);
|
|
this.byteLength += t.length
|
|
};
|
|
t.prototype.findNextStartCode = function() {
|
|
for (var t = this.index + 7 >> 3; t < this.byteLength; t++) {
|
|
if (this.bytes[t] == 0 && this.bytes[t + 1] == 0 && this.bytes[t + 2] == 1) {
|
|
this.index = t + 4 << 3;
|
|
return this.bytes[t + 3]
|
|
}
|
|
}
|
|
this.index = this.byteLength << 3;
|
|
return -1
|
|
};
|
|
t.prototype.findStartCode = function(t) {
|
|
var e = 0;
|
|
while (true) {
|
|
e = this.findNextStartCode();
|
|
if (e === t || e === -1) {
|
|
return e
|
|
}
|
|
}
|
|
return -1
|
|
};
|
|
t.prototype.nextBytesAreStartCode = function() {
|
|
var t = this.index + 7 >> 3;
|
|
return t >= this.byteLength || this.bytes[t] == 0 && this.bytes[t + 1] == 0 && this.bytes[t + 2] == 1
|
|
};
|
|
t.prototype.peek = function(t) {
|
|
var e = this.index;
|
|
var i = 0;
|
|
while (t) {
|
|
var r = this.bytes[e >> 3],
|
|
s = 8 - (e & 7),
|
|
o = s < t ? s : t,
|
|
h = s - o,
|
|
n = 255 >> 8 - o;
|
|
i = i << o | (r & n << h) >> h;
|
|
e += o;
|
|
t -= o
|
|
}
|
|
return i
|
|
};
|
|
t.prototype.read = function(t) {
|
|
var e = this.peek(t);
|
|
this.index += t;
|
|
return e
|
|
};
|
|
t.prototype.skip = function(t) {
|
|
return this.index += t
|
|
};
|
|
t.prototype.rewind = function(t) {
|
|
this.index = Math.max(this.index - t, 0)
|
|
};
|
|
t.prototype.has = function(t) {
|
|
return (this.byteLength << 3) - this.index >= t
|
|
};
|
|
t.MODE = {
|
|
EVICT: 1,
|
|
EXPAND: 2
|
|
};
|
|
return t
|
|
}();
|
|
AMT.Demuxer.TS = function() {
|
|
"use strict";
|
|
var t = function(t) {
|
|
this.bits = null;
|
|
this.leftoverBytes = null;
|
|
this.guessVideoFrameEnd = true;
|
|
this.pidsToStreamIds = {};
|
|
this.pesPacketInfo = {};
|
|
this.startTime = 0;
|
|
this.currentTime = 0
|
|
};
|
|
t.prototype.connect = function(t, e) {
|
|
this.pesPacketInfo[t] = {
|
|
destination: e,
|
|
currentLength: 0,
|
|
totalLength: 0,
|
|
pts: 0,
|
|
buffers: []
|
|
}
|
|
};
|
|
t.prototype.write = function(t) {
|
|
if (this.leftoverBytes) {
|
|
var e = t.byteLength + this.leftoverBytes.byteLength;
|
|
this.bits = new AMT.BitBuffer(e);
|
|
this.bits.write([this.leftoverBytes, t])
|
|
} else {
|
|
this.bits = new AMT.BitBuffer(t)
|
|
}
|
|
while (this.bits.has(188 << 3) && this.parsePacket()) {}
|
|
var i = this.bits.byteLength - (this.bits.index >> 3);
|
|
this.leftoverBytes = i > 0 ? this.bits.bytes.subarray(this.bits.index >> 3) : null
|
|
};
|
|
t.prototype.parsePacket = function() {
|
|
if (this.bits.read(8) !== 71) {
|
|
if (!this.resync()) {
|
|
return false
|
|
}
|
|
}
|
|
var t = (this.bits.index >> 3) + 187;
|
|
var e = this.bits.read(1),
|
|
i = this.bits.read(1),
|
|
r = this.bits.read(1),
|
|
s = this.bits.read(13),
|
|
o = this.bits.read(2),
|
|
h = this.bits.read(2),
|
|
n = this.bits.read(4);
|
|
var a = this.pidsToStreamIds[s];
|
|
if (i && a) {
|
|
var d = this.pesPacketInfo[a];
|
|
if (d && d.currentLength) {
|
|
this.packetComplete(d)
|
|
}
|
|
}
|
|
if (h & 1) {
|
|
if (h & 2) {
|
|
var c = this.bits.read(8);
|
|
this.bits.skip(c << 3)
|
|
}
|
|
if (i && this.bits.nextBytesAreStartCode()) {
|
|
this.bits.skip(24);
|
|
a = this.bits.read(8);
|
|
this.pidsToStreamIds[s] = a;
|
|
var f = this.bits.read(16);
|
|
this.bits.skip(8);
|
|
var u = this.bits.read(2);
|
|
this.bits.skip(6);
|
|
var l = this.bits.read(8);
|
|
var p = this.bits.index + (l << 3);
|
|
var d = this.pesPacketInfo[a];
|
|
if (d) {
|
|
var m = 0;
|
|
if (u & 2) {
|
|
this.bits.skip(4);
|
|
var b = this.bits.read(3);
|
|
this.bits.skip(1);
|
|
var T = this.bits.read(15);
|
|
this.bits.skip(1);
|
|
var y = this.bits.read(15);
|
|
this.bits.skip(1);
|
|
m = (b * 1073741824 + T * 32768 + y) / 9e4;
|
|
this.currentTime = m;
|
|
if (this.startTime === -1) {
|
|
this.startTime = m
|
|
}
|
|
}
|
|
var w = f ? f - l - 3 : 0;
|
|
this.packetStart(d, m, w)
|
|
}
|
|
this.bits.index = p
|
|
}
|
|
if (a) {
|
|
var d = this.pesPacketInfo[a];
|
|
if (d) {
|
|
var v = this.bits.index >> 3;
|
|
var C = this.packetAddData(d, v, t);
|
|
var A = !i && h & 2;
|
|
if (C || this.guessVideoFrameEnd && A) {
|
|
this.packetComplete(d)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.bits.index = t << 3;
|
|
return true
|
|
};
|
|
t.prototype.resync = function() {
|
|
if (!this.bits.has(188 * 6 << 3)) {
|
|
return false
|
|
}
|
|
var t = this.bits.index >> 3;
|
|
for (var e = 0; e < 187; e++) {
|
|
if (this.bits.bytes[t + e] === 71) {
|
|
var i = true;
|
|
for (var r = 1; r < 5; r++) {
|
|
if (this.bits.bytes[t + e + 188 * r] !== 71) {
|
|
i = false;
|
|
break
|
|
}
|
|
}
|
|
if (i) {
|
|
this.bits.index = t + e + 1 << 3;
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
this.bits.skip(187 << 3);
|
|
return false
|
|
};
|
|
t.prototype.packetStart = function(t, e, i) {
|
|
t.totalLength = i;
|
|
t.currentLength = 0;
|
|
t.pts = e
|
|
};
|
|
t.prototype.packetAddData = function(t, e, i) {
|
|
t.buffers.push(this.bits.bytes.subarray(e, i));
|
|
t.currentLength += i - e;
|
|
var r = t.totalLength !== 0 && t.currentLength >= t.totalLength;
|
|
return r
|
|
};
|
|
t.prototype.packetComplete = function(t) {
|
|
t.destination.write(t.pts, t.buffers);
|
|
t.totalLength = 0;
|
|
t.currentLength = 0;
|
|
t.buffers = []
|
|
};
|
|
t.STREAM = {
|
|
PACK_HEADER: 186,
|
|
SYSTEM_HEADER: 187,
|
|
PROGRAM_MAP: 188,
|
|
PRIVATE_1: 189,
|
|
PADDING: 190,
|
|
PRIVATE_2: 191,
|
|
AUDIO_1: 192,
|
|
VIDEO_1: 224,
|
|
DIRECTORY: 255
|
|
};
|
|
return t
|
|
}();
|
|
AMT.Decoder.Base = function() {
|
|
"use strict";
|
|
var t = function(t) {
|
|
this.destination = null;
|
|
this.canPlay = false;
|
|
this.collectTimestamps = !t.streaming;
|
|
this.timestamps = [];
|
|
this.timestampIndex = 0;
|
|
this.startTime = 0;
|
|
this.decodedTime = 0;
|
|
Object.defineProperty(this, "currentTime", {
|
|
get: this.getCurrentTime
|
|
})
|
|
};
|
|
t.prototype.connect = function(t) {
|
|
this.destination = t
|
|
};
|
|
t.prototype.write = function(t, e) {
|
|
if (this.collectTimestamps) {
|
|
if (this.timestamps.length === 0) {
|
|
this.startTime = t;
|
|
this.decodedTime = t
|
|
}
|
|
this.timestamps.push({
|
|
index: this.bits.byteLength << 3,
|
|
time: t
|
|
})
|
|
}
|
|
this.bits.write(e);
|
|
this.canPlay = true
|
|
};
|
|
t.prototype.seek = function(t) {
|
|
if (!this.collectTimestamps) {
|
|
return
|
|
}
|
|
this.timestampIndex = 0;
|
|
for (var e = 0; e < this.timestamps.length; e++) {
|
|
if (this.timestamps[e].time > t) {
|
|
break
|
|
}
|
|
this.timestampIndex = e
|
|
}
|
|
var i = this.timestamps[this.timestampIndex];
|
|
if (i) {
|
|
this.bits.index = i.index;
|
|
this.decodedTime = i.time
|
|
} else {
|
|
this.bits.index = 0;
|
|
this.decodedTime = this.startTime
|
|
}
|
|
};
|
|
t.prototype.decode = function() {
|
|
this.advanceDecodedTime(0)
|
|
};
|
|
t.prototype.advanceDecodedTime = function(t) {
|
|
if (this.collectTimestamps) {
|
|
var e = -1;
|
|
for (var i = this.timestampIndex; i < this.timestamps.length; i++) {
|
|
if (this.timestamps[i].index > this.bits.index) {
|
|
break
|
|
}
|
|
e = i
|
|
}
|
|
if (e !== -1 && e !== this.timestampIndex) {
|
|
this.timestampIndex = e;
|
|
this.decodedTime = this.timestamps[this.timestampIndex].time;
|
|
return
|
|
}
|
|
}
|
|
this.decodedTime += t
|
|
};
|
|
t.prototype.getCurrentTime = function() {
|
|
return this.decodedTime
|
|
};
|
|
return t
|
|
}();
|
|
AMT.Decoder.MPEG1Video = function() {
|
|
"use strict";
|
|
var t = function(t) {
|
|
AMT.Decoder.Base.call(this, t);
|
|
var e = t.videoBufferSize || 512 * 1024;
|
|
var i = t.streaming ? AMT.BitBuffer.MODE.EVICT : AMT.BitBuffer.MODE.EXPAND;
|
|
this.bits = new AMT.BitBuffer(e, i);
|
|
this.customIntraQuantMatrix = new Uint8Array(64);
|
|
this.customNonIntraQuantMatrix = new Uint8Array(64);
|
|
this.blockData = new Int32Array(64);
|
|
this.currentFrame = 0;
|
|
this.decodeFirstFrame = t.decodeFirstFrame !== false
|
|
};
|
|
t.prototype = Object.create(AMT.Decoder.Base.prototype);
|
|
t.prototype.constructor = t;
|
|
t.prototype.write = function(e, i) {
|
|
AMT.Decoder.Base.prototype.write.call(this, e, i);
|
|
if (!this.hasSequenceHeader) {
|
|
if (this.bits.findStartCode(t.START.SEQUENCE) === -1) {
|
|
return false
|
|
}
|
|
this.decodeSequenceHeader();
|
|
if (this.decodeFirstFrame) {
|
|
this.decode()
|
|
}
|
|
}
|
|
};
|
|
t.prototype.decode = function() {
|
|
if (!this.hasSequenceHeader) {
|
|
return false
|
|
}
|
|
if (this.bits.findStartCode(t.START.PICTURE) === -1) {
|
|
var e = this.bits.byteLength - (this.bits.index >> 3);
|
|
return false
|
|
}
|
|
this.decodePicture();
|
|
this.advanceDecodedTime(1 / this.frameRate);
|
|
return true
|
|
};
|
|
t.prototype.readHuffman = function(t) {
|
|
var e = 0;
|
|
do {
|
|
e = t[e + this.bits.read(1)]
|
|
} while (e >= 0 && t[e] !== 0);
|
|
return t[e + 2]
|
|
};
|
|
t.prototype.frameRate = 30;
|
|
t.prototype.decodeSequenceHeader = function() {
|
|
var e = this.bits.read(12),
|
|
i = this.bits.read(12);
|
|
this.bits.skip(4);
|
|
this.frameRate = t.PICTURE_RATE[this.bits.read(4)];
|
|
this.bits.skip(18 + 1 + 10 + 1);
|
|
if (e !== this.width || i !== this.height) {
|
|
this.width = e;
|
|
this.height = i;
|
|
this.initBuffers();
|
|
if (this.destination) {
|
|
this.destination.resize(e, i)
|
|
}
|
|
}
|
|
if (this.bits.read(1)) {
|
|
for (var r = 0; r < 64; r++) {
|
|
this.customIntraQuantMatrix[t.ZIG_ZAG[r]] = this.bits.read(8)
|
|
}
|
|
this.intraQuantMatrix = this.customIntraQuantMatrix
|
|
}
|
|
if (this.bits.read(1)) {
|
|
for (var r = 0; r < 64; r++) {
|
|
var s = t.ZIG_ZAG[r];
|
|
this.customNonIntraQuantMatrix[s] = this.bits.read(8)
|
|
}
|
|
this.nonIntraQuantMatrix = this.customNonIntraQuantMatrix
|
|
}
|
|
this.hasSequenceHeader = true
|
|
};
|
|
t.prototype.initBuffers = function() {
|
|
this.intraQuantMatrix = t.DEFAULT_INTRA_QUANT_MATRIX;
|
|
this.nonIntraQuantMatrix = t.DEFAULT_NON_INTRA_QUANT_MATRIX;
|
|
this.mbWidth = this.width + 15 >> 4;
|
|
this.mbHeight = this.height + 15 >> 4;
|
|
this.mbSize = this.mbWidth * this.mbHeight;
|
|
this.codedWidth = this.mbWidth << 4;
|
|
this.codedHeight = this.mbHeight << 4;
|
|
this.codedSize = this.codedWidth * this.codedHeight;
|
|
this.halfWidth = this.mbWidth << 3;
|
|
this.halfHeight = this.mbHeight << 3;
|
|
this.currentY = new Uint8ClampedArray(this.codedSize);
|
|
this.currentY32 = new Uint32Array(this.currentY.buffer);
|
|
this.currentCr = new Uint8ClampedArray(this.codedSize >> 2);
|
|
this.currentCr32 = new Uint32Array(this.currentCr.buffer);
|
|
this.currentCb = new Uint8ClampedArray(this.codedSize >> 2);
|
|
this.currentCb32 = new Uint32Array(this.currentCb.buffer);
|
|
this.forwardY = new Uint8ClampedArray(this.codedSize);
|
|
this.forwardY32 = new Uint32Array(this.forwardY.buffer);
|
|
this.forwardCr = new Uint8ClampedArray(this.codedSize >> 2);
|
|
this.forwardCr32 = new Uint32Array(this.forwardCr.buffer);
|
|
this.forwardCb = new Uint8ClampedArray(this.codedSize >> 2);
|
|
this.forwardCb32 = new Uint32Array(this.forwardCb.buffer)
|
|
};
|
|
t.prototype.currentY = null;
|
|
t.prototype.currentCr = null;
|
|
t.prototype.currentCb = null;
|
|
t.prototype.pictureType = 0;
|
|
t.prototype.forwardY = null;
|
|
t.prototype.forwardCr = null;
|
|
t.prototype.forwardCb = null;
|
|
t.prototype.fullPelForward = false;
|
|
t.prototype.forwardFCode = 0;
|
|
t.prototype.forwardRSize = 0;
|
|
t.prototype.forwardF = 0;
|
|
t.prototype.decodePicture = function(e) {
|
|
this.currentFrame++;
|
|
this.bits.skip(10);
|
|
this.pictureType = this.bits.read(3);
|
|
this.bits.skip(16);
|
|
if (this.pictureType <= 0 || this.pictureType >= t.PICTURE_TYPE.B) {
|
|
return
|
|
}
|
|
if (this.pictureType === t.PICTURE_TYPE.PREDICTIVE) {
|
|
this.fullPelForward = this.bits.read(1);
|
|
this.forwardFCode = this.bits.read(3);
|
|
if (this.forwardFCode === 0) {
|
|
return
|
|
}
|
|
this.forwardRSize = this.forwardFCode - 1;
|
|
this.forwardF = 1 << this.forwardRSize
|
|
}
|
|
var i = 0;
|
|
do {
|
|
i = this.bits.findNextStartCode()
|
|
} while (i === t.START.EXTENSION || i === t.START.USER_DATA);
|
|
while (i >= t.START.SLICE_FIRST && i <= t.START.SLICE_LAST) {
|
|
this.decodeSlice(i & 255);
|
|
i = this.bits.findNextStartCode()
|
|
}
|
|
if (i !== -1) {
|
|
this.bits.rewind(32)
|
|
}
|
|
if (this.destination) {
|
|
this.destination.render(this.currentY, this.currentCr, this.currentCb)
|
|
}
|
|
if (this.pictureType === t.PICTURE_TYPE.INTRA || this.pictureType === t.PICTURE_TYPE.PREDICTIVE) {
|
|
var r = this.forwardY,
|
|
s = this.forwardY32,
|
|
o = this.forwardCr,
|
|
h = this.forwardCr32,
|
|
n = this.forwardCb,
|
|
a = this.forwardCb32;
|
|
this.forwardY = this.currentY;
|
|
this.forwardY32 = this.currentY32;
|
|
this.forwardCr = this.currentCr;
|
|
this.forwardCr32 = this.currentCr32;
|
|
this.forwardCb = this.currentCb;
|
|
this.forwardCb32 = this.currentCb32;
|
|
this.currentY = r;
|
|
this.currentY32 = s;
|
|
this.currentCr = o;
|
|
this.currentCr32 = h;
|
|
this.currentCb = n;
|
|
this.currentCb32 = a
|
|
}
|
|
};
|
|
t.prototype.quantizerScale = 0;
|
|
t.prototype.sliceBegin = false;
|
|
t.prototype.decodeSlice = function(t) {
|
|
this.sliceBegin = true;
|
|
this.macroblockAddress = (t - 1) * this.mbWidth - 1;
|
|
this.motionFwH = this.motionFwHPrev = 0;
|
|
this.motionFwV = this.motionFwVPrev = 0;
|
|
this.dcPredictorY = 128;
|
|
this.dcPredictorCr = 128;
|
|
this.dcPredictorCb = 128;
|
|
this.quantizerScale = this.bits.read(5);
|
|
while (this.bits.read(1)) {
|
|
this.bits.skip(8)
|
|
}
|
|
do {
|
|
this.decodeMacroblock()
|
|
} while (!this.bits.nextBytesAreStartCode())
|
|
};
|
|
t.prototype.macroblockAddress = 0;
|
|
t.prototype.mbRow = 0;
|
|
t.prototype.mbCol = 0;
|
|
t.prototype.macroblockType = 0;
|
|
t.prototype.macroblockIntra = false;
|
|
t.prototype.macroblockMotFw = false;
|
|
t.prototype.motionFwH = 0;
|
|
t.prototype.motionFwV = 0;
|
|
t.prototype.motionFwHPrev = 0;
|
|
t.prototype.motionFwVPrev = 0;
|
|
t.prototype.decodeMacroblock = function() {
|
|
var e = 0,
|
|
i = this.readHuffman(t.MACROBLOCK_ADDRESS_INCREMENT);
|
|
while (i === 34) {
|
|
i = this.readHuffman(t.MACROBLOCK_ADDRESS_INCREMENT)
|
|
}
|
|
while (i === 35) {
|
|
e += 33;
|
|
i = this.readHuffman(t.MACROBLOCK_ADDRESS_INCREMENT)
|
|
}
|
|
e += i;
|
|
if (this.sliceBegin) {
|
|
this.sliceBegin = false;
|
|
this.macroblockAddress += e
|
|
} else {
|
|
if (this.macroblockAddress + e >= this.mbSize) {
|
|
return
|
|
}
|
|
if (e > 1) {
|
|
this.dcPredictorY = 128;
|
|
this.dcPredictorCr = 128;
|
|
this.dcPredictorCb = 128;
|
|
if (this.pictureType === t.PICTURE_TYPE.PREDICTIVE) {
|
|
this.motionFwH = this.motionFwHPrev = 0;
|
|
this.motionFwV = this.motionFwVPrev = 0
|
|
}
|
|
}
|
|
while (e > 1) {
|
|
this.macroblockAddress++;
|
|
this.mbRow = this.macroblockAddress / this.mbWidth | 0;
|
|
this.mbCol = this.macroblockAddress % this.mbWidth;
|
|
this.copyMacroblock(this.motionFwH, this.motionFwV, this.forwardY, this.forwardCr, this.forwardCb);
|
|
e--
|
|
}
|
|
this.macroblockAddress++
|
|
}
|
|
this.mbRow = this.macroblockAddress / this.mbWidth | 0;
|
|
this.mbCol = this.macroblockAddress % this.mbWidth;
|
|
var r = t.MACROBLOCK_TYPE[this.pictureType];
|
|
this.macroblockType = this.readHuffman(r);
|
|
this.macroblockIntra = this.macroblockType & 1;
|
|
this.macroblockMotFw = this.macroblockType & 8;
|
|
if ((this.macroblockType & 16) !== 0) {
|
|
this.quantizerScale = this.bits.read(5)
|
|
}
|
|
if (this.macroblockIntra) {
|
|
this.motionFwH = this.motionFwHPrev = 0;
|
|
this.motionFwV = this.motionFwVPrev = 0
|
|
} else {
|
|
this.dcPredictorY = 128;
|
|
this.dcPredictorCr = 128;
|
|
this.dcPredictorCb = 128;
|
|
this.decodeMotionVectors();
|
|
this.copyMacroblock(this.motionFwH, this.motionFwV, this.forwardY, this.forwardCr, this.forwardCb)
|
|
}
|
|
var s = (this.macroblockType & 2) !== 0 ? this.readHuffman(t.CODE_BLOCK_PATTERN) : this.macroblockIntra ? 63 : 0;
|
|
for (var o = 0, h = 32; o < 6; o++) {
|
|
if ((s & h) !== 0) {
|
|
this.decodeBlock(o)
|
|
}
|
|
h >>= 1
|
|
}
|
|
};
|
|
t.prototype.decodeMotionVectors = function() {
|
|
var e, i, r = 0;
|
|
if (this.macroblockMotFw) {
|
|
e = this.readHuffman(t.MOTION);
|
|
if (e !== 0 && this.forwardF !== 1) {
|
|
r = this.bits.read(this.forwardRSize);
|
|
i = (Math.abs(e) - 1 << this.forwardRSize) + r + 1;
|
|
if (e < 0) {
|
|
i = -i
|
|
}
|
|
} else {
|
|
i = e
|
|
}
|
|
this.motionFwHPrev += i;
|
|
if (this.motionFwHPrev > (this.forwardF << 4) - 1) {
|
|
this.motionFwHPrev -= this.forwardF << 5
|
|
} else if (this.motionFwHPrev < -this.forwardF << 4) {
|
|
this.motionFwHPrev += this.forwardF << 5
|
|
}
|
|
this.motionFwH = this.motionFwHPrev;
|
|
if (this.fullPelForward) {
|
|
this.motionFwH <<= 1
|
|
}
|
|
e = this.readHuffman(t.MOTION);
|
|
if (e !== 0 && this.forwardF !== 1) {
|
|
r = this.bits.read(this.forwardRSize);
|
|
i = (Math.abs(e) - 1 << this.forwardRSize) + r + 1;
|
|
if (e < 0) {
|
|
i = -i
|
|
}
|
|
} else {
|
|
i = e
|
|
}
|
|
this.motionFwVPrev += i;
|
|
if (this.motionFwVPrev > (this.forwardF << 4) - 1) {
|
|
this.motionFwVPrev -= this.forwardF << 5
|
|
} else if (this.motionFwVPrev < -this.forwardF << 4) {
|
|
this.motionFwVPrev += this.forwardF << 5
|
|
}
|
|
this.motionFwV = this.motionFwVPrev;
|
|
if (this.fullPelForward) {
|
|
this.motionFwV <<= 1
|
|
}
|
|
} else if (this.pictureType === t.PICTURE_TYPE.PREDICTIVE) {
|
|
this.motionFwH = this.motionFwHPrev = 0;
|
|
this.motionFwV = this.motionFwVPrev = 0
|
|
}
|
|
};
|
|
t.prototype.copyMacroblock = function(t, e, i, r, s) {
|
|
var o, h, n, a, d, c, f, u, l;
|
|
var p = this.currentY32,
|
|
m = this.currentCb32,
|
|
b = this.currentCr32;
|
|
o = this.codedWidth;
|
|
h = o - 16;
|
|
n = t >> 1;
|
|
a = e >> 1;
|
|
d = (t & 1) === 1;
|
|
c = (e & 1) === 1;
|
|
f = ((this.mbRow << 4) + a) * o + (this.mbCol << 4) + n;
|
|
u = this.mbRow * o + this.mbCol << 2;
|
|
l = u + (o << 2);
|
|
var T, y, w, v;
|
|
if (d) {
|
|
if (c) {
|
|
while (u < l) {
|
|
y = i[f] + i[f + o];
|
|
f++;
|
|
for (T = 0; T < 4; T++) {
|
|
w = i[f] + i[f + o];
|
|
f++;
|
|
v = y + w + 2 >> 2 & 255;
|
|
y = i[f] + i[f + o];
|
|
f++;
|
|
v |= y + w + 2 << 6 & 65280;
|
|
w = i[f] + i[f + o];
|
|
f++;
|
|
v |= y + w + 2 << 14 & 16711680;
|
|
y = i[f] + i[f + o];
|
|
f++;
|
|
v |= y + w + 2 << 22 & 4278190080;
|
|
p[u++] = v
|
|
}
|
|
u += h >> 2;
|
|
f += h - 1
|
|
}
|
|
} else {
|
|
while (u < l) {
|
|
y = i[f++];
|
|
for (T = 0; T < 4; T++) {
|
|
w = i[f++];
|
|
v = y + w + 1 >> 1 & 255;
|
|
y = i[f++];
|
|
v |= y + w + 1 << 7 & 65280;
|
|
w = i[f++];
|
|
v |= y + w + 1 << 15 & 16711680;
|
|
y = i[f++];
|
|
v |= y + w + 1 << 23 & 4278190080;
|
|
p[u++] = v
|
|
}
|
|
u += h >> 2;
|
|
f += h - 1
|
|
}
|
|
}
|
|
} else {
|
|
if (c) {
|
|
while (u < l) {
|
|
for (T = 0; T < 4; T++) {
|
|
v = i[f] + i[f + o] + 1 >> 1 & 255;
|
|
f++;
|
|
v |= i[f] + i[f + o] + 1 << 7 & 65280;
|
|
f++;
|
|
v |= i[f] + i[f + o] + 1 << 15 & 16711680;
|
|
f++;
|
|
v |= i[f] + i[f + o] + 1 << 23 & 4278190080;
|
|
f++;
|
|
p[u++] = v
|
|
}
|
|
u += h >> 2;
|
|
f += h
|
|
}
|
|
} else {
|
|
while (u < l) {
|
|
for (T = 0; T < 4; T++) {
|
|
v = i[f];
|
|
f++;
|
|
v |= i[f] << 8;
|
|
f++;
|
|
v |= i[f] << 16;
|
|
f++;
|
|
v |= i[f] << 24;
|
|
f++;
|
|
p[u++] = v
|
|
}
|
|
u += h >> 2;
|
|
f += h
|
|
}
|
|
}
|
|
}
|
|
o = this.halfWidth;
|
|
h = o - 8;
|
|
n = t / 2 >> 1;
|
|
a = e / 2 >> 1;
|
|
d = (t / 2 & 1) === 1;
|
|
c = (e / 2 & 1) === 1;
|
|
f = ((this.mbRow << 3) + a) * o + (this.mbCol << 3) + n;
|
|
u = this.mbRow * o + this.mbCol << 1;
|
|
l = u + (o << 1);
|
|
var C, A, E, g, R, I;
|
|
if (d) {
|
|
if (c) {
|
|
while (u < l) {
|
|
C = r[f] + r[f + o];
|
|
g = s[f] + s[f + o];
|
|
f++;
|
|
for (T = 0; T < 2; T++) {
|
|
A = r[f] + r[f + o];
|
|
R = s[f] + s[f + o];
|
|
f++;
|
|
E = C + A + 2 >> 2 & 255;
|
|
I = g + R + 2 >> 2 & 255;
|
|
C = r[f] + r[f + o];
|
|
g = s[f] + s[f + o];
|
|
f++;
|
|
E |= C + A + 2 << 6 & 65280;
|
|
I |= g + R + 2 << 6 & 65280;
|
|
A = r[f] + r[f + o];
|
|
R = s[f] + s[f + o];
|
|
f++;
|
|
E |= C + A + 2 << 14 & 16711680;
|
|
I |= g + R + 2 << 14 & 16711680;
|
|
C = r[f] + r[f + o];
|
|
g = s[f] + s[f + o];
|
|
f++;
|
|
E |= C + A + 2 << 22 & 4278190080;
|
|
I |= g + R + 2 << 22 & 4278190080;
|
|
b[u] = E;
|
|
m[u] = I;
|
|
u++
|
|
}
|
|
u += h >> 2;
|
|
f += h - 1
|
|
}
|
|
} else {
|
|
while (u < l) {
|
|
C = r[f];
|
|
g = s[f];
|
|
f++;
|
|
for (T = 0; T < 2; T++) {
|
|
A = r[f];
|
|
R = s[f++];
|
|
E = C + A + 1 >> 1 & 255;
|
|
I = g + R + 1 >> 1 & 255;
|
|
C = r[f];
|
|
g = s[f++];
|
|
E |= C + A + 1 << 7 & 65280;
|
|
I |= g + R + 1 << 7 & 65280;
|
|
A = r[f];
|
|
R = s[f++];
|
|
E |= C + A + 1 << 15 & 16711680;
|
|
I |= g + R + 1 << 15 & 16711680;
|
|
C = r[f];
|
|
g = s[f++];
|
|
E |= C + A + 1 << 23 & 4278190080;
|
|
I |= g + R + 1 << 23 & 4278190080;
|
|
b[u] = E;
|
|
m[u] = I;
|
|
u++
|
|
}
|
|
u += h >> 2;
|
|
f += h - 1
|
|
}
|
|
}
|
|
} else {
|
|
if (c) {
|
|
while (u < l) {
|
|
for (T = 0; T < 2; T++) {
|
|
E = r[f] + r[f + o] + 1 >> 1 & 255;
|
|
I = s[f] + s[f + o] + 1 >> 1 & 255;
|
|
f++;
|
|
E |= r[f] + r[f + o] + 1 << 7 & 65280;
|
|
I |= s[f] + s[f + o] + 1 << 7 & 65280;
|
|
f++;
|
|
E |= r[f] + r[f + o] + 1 << 15 & 16711680;
|
|
I |= s[f] + s[f + o] + 1 << 15 & 16711680;
|
|
f++;
|
|
E |= r[f] + r[f + o] + 1 << 23 & 4278190080;
|
|
I |= s[f] + s[f + o] + 1 << 23 & 4278190080;
|
|
f++;
|
|
b[u] = E;
|
|
m[u] = I;
|
|
u++
|
|
}
|
|
u += h >> 2;
|
|
f += h
|
|
}
|
|
} else {
|
|
while (u < l) {
|
|
for (T = 0; T < 2; T++) {
|
|
E = r[f];
|
|
I = s[f];
|
|
f++;
|
|
E |= r[f] << 8;
|
|
I |= s[f] << 8;
|
|
f++;
|
|
E |= r[f] << 16;
|
|
I |= s[f] << 16;
|
|
f++;
|
|
E |= r[f] << 24;
|
|
I |= s[f] << 24;
|
|
f++;
|
|
b[u] = E;
|
|
m[u] = I;
|
|
u++
|
|
}
|
|
u += h >> 2;
|
|
f += h
|
|
}
|
|
}
|
|
}
|
|
};
|
|
t.prototype.dcPredictorY = 0;
|
|
t.prototype.dcPredictorCr = 0;
|
|
t.prototype.dcPredictorCb = 0;
|
|
t.prototype.blockData = null;
|
|
t.prototype.decodeBlock = function(e) {
|
|
var i = 0,
|
|
r;
|
|
if (this.macroblockIntra) {
|
|
var s, o;
|
|
if (e < 4) {
|
|
s = this.dcPredictorY;
|
|
o = this.readHuffman(t.DCT_DC_SIZE_LUMINANCE)
|
|
} else {
|
|
s = e === 4 ? this.dcPredictorCr : this.dcPredictorCb;
|
|
o = this.readHuffman(t.DCT_DC_SIZE_CHROMINANCE)
|
|
}
|
|
if (o > 0) {
|
|
var h = this.bits.read(o);
|
|
if ((h & 1 << o - 1) !== 0) {
|
|
this.blockData[0] = s + h
|
|
} else {
|
|
this.blockData[0] = s + (-1 << o | h + 1)
|
|
}
|
|
} else {
|
|
this.blockData[0] = s
|
|
}
|
|
if (e < 4) {
|
|
this.dcPredictorY = this.blockData[0]
|
|
} else if (e === 4) {
|
|
this.dcPredictorCr = this.blockData[0]
|
|
} else {
|
|
this.dcPredictorCb = this.blockData[0]
|
|
}
|
|
this.blockData[0] <<= 3 + 5;
|
|
r = this.intraQuantMatrix;
|
|
i = 1
|
|
} else {
|
|
r = this.nonIntraQuantMatrix
|
|
}
|
|
var n = 0;
|
|
while (true) {
|
|
var a = 0,
|
|
d = this.readHuffman(t.DCT_COEFF);
|
|
if (d === 1 && i > 0 && this.bits.read(1) === 0) {
|
|
break
|
|
}
|
|
if (d === 65535) {
|
|
a = this.bits.read(6);
|
|
n = this.bits.read(8);
|
|
if (n === 0) {
|
|
n = this.bits.read(8)
|
|
} else if (n === 128) {
|
|
n = this.bits.read(8) - 256
|
|
} else if (n > 128) {
|
|
n = n - 256
|
|
}
|
|
} else {
|
|
a = d >> 8;
|
|
n = d & 255;
|
|
if (this.bits.read(1)) {
|
|
n = -n
|
|
}
|
|
}
|
|
i += a;
|
|
var c = t.ZIG_ZAG[i];
|
|
i++;
|
|
n <<= 1;
|
|
if (!this.macroblockIntra) {
|
|
n += n < 0 ? -1 : 1
|
|
}
|
|
n = n * this.quantizerScale * r[c] >> 4;
|
|
if ((n & 1) === 0) {
|
|
n -= n > 0 ? 1 : -1
|
|
}
|
|
if (n > 2047) {
|
|
n = 2047
|
|
} else if (n < -2048) {
|
|
n = -2048
|
|
}
|
|
this.blockData[c] = n * t.PREMULTIPLIER_MATRIX[c]
|
|
}
|
|
var f, u, l;
|
|
if (e < 4) {
|
|
f = this.currentY;
|
|
l = this.codedWidth - 8;
|
|
u = this.mbRow * this.codedWidth + this.mbCol << 4;
|
|
if ((e & 1) !== 0) {
|
|
u += 8
|
|
}
|
|
if ((e & 2) !== 0) {
|
|
u += this.codedWidth << 3
|
|
}
|
|
} else {
|
|
f = e === 4 ? this.currentCb : this.currentCr;
|
|
l = (this.codedWidth >> 1) - 8;
|
|
u = (this.mbRow * this.codedWidth << 2) + (this.mbCol << 3)
|
|
}
|
|
if (this.macroblockIntra) {
|
|
if (i === 1) {
|
|
t.CopyValueToDestination(this.blockData[0] + 128 >> 8, f, u, l);
|
|
this.blockData[0] = 0
|
|
} else {
|
|
t.IDCT(this.blockData);
|
|
t.CopyBlockToDestination(this.blockData, f, u, l);
|
|
AMT.Fill(this.blockData, 0)
|
|
}
|
|
} else {
|
|
if (i === 1) {
|
|
t.AddValueToDestination(this.blockData[0] + 128 >> 8, f, u, l);
|
|
this.blockData[0] = 0
|
|
} else {
|
|
t.IDCT(this.blockData);
|
|
t.AddBlockToDestination(this.blockData, f, u, l);
|
|
AMT.Fill(this.blockData, 0)
|
|
}
|
|
}
|
|
i = 0
|
|
};
|
|
t.CopyBlockToDestination = function(t, e, i, r) {
|
|
for (var s = 0; s < 64; s += 8, i += r + 8) {
|
|
e[i + 0] = t[s + 0];
|
|
e[i + 1] = t[s + 1];
|
|
e[i + 2] = t[s + 2];
|
|
e[i + 3] = t[s + 3];
|
|
e[i + 4] = t[s + 4];
|
|
e[i + 5] = t[s + 5];
|
|
e[i + 6] = t[s + 6];
|
|
e[i + 7] = t[s + 7]
|
|
}
|
|
};
|
|
t.AddBlockToDestination = function(t, e, i, r) {
|
|
for (var s = 0; s < 64; s += 8, i += r + 8) {
|
|
e[i + 0] += t[s + 0];
|
|
e[i + 1] += t[s + 1];
|
|
e[i + 2] += t[s + 2];
|
|
e[i + 3] += t[s + 3];
|
|
e[i + 4] += t[s + 4];
|
|
e[i + 5] += t[s + 5];
|
|
e[i + 6] += t[s + 6];
|
|
e[i + 7] += t[s + 7]
|
|
}
|
|
};
|
|
t.CopyValueToDestination = function(t, e, i, r) {
|
|
for (var s = 0; s < 64; s += 8, i += r + 8) {
|
|
e[i + 0] = t;
|
|
e[i + 1] = t;
|
|
e[i + 2] = t;
|
|
e[i + 3] = t;
|
|
e[i + 4] = t;
|
|
e[i + 5] = t;
|
|
e[i + 6] = t;
|
|
e[i + 7] = t
|
|
}
|
|
};
|
|
t.AddValueToDestination = function(t, e, i, r) {
|
|
for (var s = 0; s < 64; s += 8, i += r + 8) {
|
|
e[i + 0] += t;
|
|
e[i + 1] += t;
|
|
e[i + 2] += t;
|
|
e[i + 3] += t;
|
|
e[i + 4] += t;
|
|
e[i + 5] += t;
|
|
e[i + 6] += t;
|
|
e[i + 7] += t
|
|
}
|
|
};
|
|
t.IDCT = function(t) {
|
|
var e, i, r, s, o, h, n, a, d, c, f, u, l, p, m, b, T, y;
|
|
for (var w = 0; w < 8; ++w) {
|
|
e = t[4 * 8 + w];
|
|
i = t[2 * 8 + w] + t[6 * 8 + w];
|
|
r = t[5 * 8 + w] - t[3 * 8 + w];
|
|
h = t[1 * 8 + w] + t[7 * 8 + w];
|
|
n = t[3 * 8 + w] + t[5 * 8 + w];
|
|
s = t[1 * 8 + w] - t[7 * 8 + w];
|
|
o = h + n;
|
|
a = t[0 * 8 + w];
|
|
l = (s * 473 - r * 196 + 128 >> 8) - o;
|
|
d = l - ((h - n) * 362 + 128 >> 8);
|
|
c = a - e;
|
|
f = ((t[2 * 8 + w] - t[6 * 8 + w]) * 362 + 128 >> 8) - i;
|
|
u = a + e;
|
|
p = c + f;
|
|
m = u + i;
|
|
b = c - f;
|
|
T = u - i;
|
|
y = -d - (r * 473 + s * 196 + 128 >> 8);
|
|
t[0 * 8 + w] = o + m;
|
|
t[1 * 8 + w] = l + p;
|
|
t[2 * 8 + w] = b - d;
|
|
t[3 * 8 + w] = T - y;
|
|
t[4 * 8 + w] = T + y;
|
|
t[5 * 8 + w] = d + b;
|
|
t[6 * 8 + w] = p - l;
|
|
t[7 * 8 + w] = m - o
|
|
}
|
|
for (var w = 0; w < 64; w += 8) {
|
|
e = t[4 + w];
|
|
i = t[2 + w] + t[6 + w];
|
|
r = t[5 + w] - t[3 + w];
|
|
h = t[1 + w] + t[7 + w];
|
|
n = t[3 + w] + t[5 + w];
|
|
s = t[1 + w] - t[7 + w];
|
|
o = h + n;
|
|
a = t[0 + w];
|
|
l = (s * 473 - r * 196 + 128 >> 8) - o;
|
|
d = l - ((h - n) * 362 + 128 >> 8);
|
|
c = a - e;
|
|
f = ((t[2 + w] - t[6 + w]) * 362 + 128 >> 8) - i;
|
|
u = a + e;
|
|
p = c + f;
|
|
m = u + i;
|
|
b = c - f;
|
|
T = u - i;
|
|
y = -d - (r * 473 + s * 196 + 128 >> 8);
|
|
t[0 + w] = o + m + 128 >> 8;
|
|
t[1 + w] = l + p + 128 >> 8;
|
|
t[2 + w] = b - d + 128 >> 8;
|
|
t[3 + w] = T - y + 128 >> 8;
|
|
t[4 + w] = T + y + 128 >> 8;
|
|
t[5 + w] = d + b + 128 >> 8;
|
|
t[6 + w] = p - l + 128 >> 8;
|
|
t[7 + w] = m - o + 128 >> 8
|
|
}
|
|
};
|
|
t.PICTURE_RATE = [0, 23.976, 24, 25, 29.97, 30, 50, 59.94, 60, 0, 0, 0, 0, 0, 0, 0];
|
|
t.ZIG_ZAG = new Uint8Array([0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63]);
|
|
t.DEFAULT_INTRA_QUANT_MATRIX = new Uint8Array([8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83]);
|
|
t.DEFAULT_NON_INTRA_QUANT_MATRIX = new Uint8Array([16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]);
|
|
t.PREMULTIPLIER_MATRIX = new Uint8Array([32, 44, 42, 38, 32, 25, 17, 9, 44, 62, 58, 52, 44, 35, 24, 12, 42, 58, 55, 49, 42, 33, 23, 12, 38, 52, 49, 44, 38, 30, 20, 10, 32, 44, 42, 38, 32, 25, 17, 9, 25, 35, 33, 30, 25, 20, 14, 7, 17, 24, 23, 20, 17, 14, 9, 5, 9, 12, 12, 10, 9, 7, 5, 2]);
|
|
t.MACROBLOCK_ADDRESS_INCREMENT = new Int16Array([1 * 3, 2 * 3, 0, 3 * 3, 4 * 3, 0, 0, 0, 1, 5 * 3, 6 * 3, 0, 7 * 3, 8 * 3, 0, 9 * 3, 10 * 3, 0, 11 * 3, 12 * 3, 0, 0, 0, 3, 0, 0, 2, 13 * 3, 14 * 3, 0, 15 * 3, 16 * 3, 0, 0, 0, 5, 0, 0, 4, 17 * 3, 18 * 3, 0, 19 * 3, 20 * 3, 0, 0, 0, 7, 0, 0, 6, 21 * 3, 22 * 3, 0, 23 * 3, 24 * 3, 0, 25 * 3, 26 * 3, 0, 27 * 3, 28 * 3, 0, -1, 29 * 3, 0, -1, 30 * 3, 0, 31 * 3, 32 * 3, 0, 33 * 3, 34 * 3, 0, 35 * 3, 36 * 3, 0, 37 * 3, 38 * 3, 0, 0, 0, 9, 0, 0, 8, 39 * 3, 40 * 3, 0, 41 * 3, 42 * 3, 0, 43 * 3, 44 * 3, 0, 45 * 3, 46 * 3, 0, 0, 0, 15, 0, 0, 14, 0, 0, 13, 0, 0, 12, 0, 0, 11, 0, 0, 10, 47 * 3, -1, 0, -1, 48 * 3, 0, 49 * 3, 50 * 3, 0, 51 * 3, 52 * 3, 0, 53 * 3, 54 * 3, 0, 55 * 3, 56 * 3, 0, 57 * 3, 58 * 3, 0, 59 * 3, 60 * 3, 0, 61 * 3, -1, 0, -1, 62 * 3, 0, 63 * 3, 64 * 3, 0, 65 * 3, 66 * 3, 0, 67 * 3, 68 * 3, 0, 69 * 3, 70 * 3, 0, 71 * 3, 72 * 3, 0, 73 * 3, 74 * 3, 0, 0, 0, 21, 0, 0, 20, 0, 0, 19, 0, 0, 18, 0, 0, 17, 0, 0, 16, 0, 0, 35, 0, 0, 34, 0, 0, 33, 0, 0, 32, 0, 0, 31, 0, 0, 30, 0, 0, 29, 0, 0, 28, 0, 0, 27, 0, 0, 26, 0, 0, 25, 0, 0, 24, 0, 0, 23, 0, 0, 22]);
|
|
t.MACROBLOCK_TYPE_INTRA = new Int8Array([1 * 3, 2 * 3, 0, -1, 3 * 3, 0, 0, 0, 1, 0, 0, 17]);
|
|
t.MACROBLOCK_TYPE_PREDICTIVE = new Int8Array([1 * 3, 2 * 3, 0, 3 * 3, 4 * 3, 0, 0, 0, 10, 5 * 3, 6 * 3, 0, 0, 0, 2, 7 * 3, 8 * 3, 0, 0, 0, 8, 9 * 3, 10 * 3, 0, 11 * 3, 12 * 3, 0, -1, 13 * 3, 0, 0, 0, 18, 0, 0, 26, 0, 0, 1, 0, 0, 17]);
|
|
t.MACROBLOCK_TYPE_B = new Int8Array([1 * 3, 2 * 3, 0, 3 * 3, 5 * 3, 0, 4 * 3, 6 * 3, 0, 8 * 3, 7 * 3, 0, 0, 0, 12, 9 * 3, 10 * 3, 0, 0, 0, 14, 13 * 3, 14 * 3, 0, 12 * 3, 11 * 3, 0, 0, 0, 4, 0, 0, 6, 18 * 3, 16 * 3, 0, 15 * 3, 17 * 3, 0, 0, 0, 8, 0, 0, 10, -1, 19 * 3, 0, 0, 0, 1, 20 * 3, 21 * 3, 0, 0, 0, 30, 0, 0, 17, 0, 0, 22, 0, 0, 26]);
|
|
t.MACROBLOCK_TYPE = [null, t.MACROBLOCK_TYPE_INTRA, t.MACROBLOCK_TYPE_PREDICTIVE, t.MACROBLOCK_TYPE_B];
|
|
t.CODE_BLOCK_PATTERN = new Int16Array([2 * 3, 1 * 3, 0, 3 * 3, 6 * 3, 0, 4 * 3, 5 * 3, 0, 8 * 3, 11 * 3, 0, 12 * 3, 13 * 3, 0, 9 * 3, 7 * 3, 0, 10 * 3, 14 * 3, 0, 20 * 3, 19 * 3, 0, 18 * 3, 16 * 3, 0, 23 * 3, 17 * 3, 0, 27 * 3, 25 * 3, 0, 21 * 3, 28 * 3, 0, 15 * 3, 22 * 3, 0, 24 * 3, 26 * 3, 0, 0, 0, 60, 35 * 3, 40 * 3, 0, 44 * 3, 48 * 3, 0, 38 * 3, 36 * 3, 0, 42 * 3, 47 * 3, 0, 29 * 3, 31 * 3, 0, 39 * 3, 32 * 3, 0, 0, 0, 32, 45 * 3, 46 * 3, 0, 33 * 3, 41 * 3, 0, 43 * 3, 34 * 3, 0, 0, 0, 4, 30 * 3, 37 * 3, 0, 0, 0, 8, 0, 0, 16, 0, 0, 44, 50 * 3, 56 * 3, 0, 0, 0, 28, 0, 0, 52, 0, 0, 62, 61 * 3, 59 * 3, 0, 52 * 3, 60 * 3, 0, 0, 0, 1, 55 * 3, 54 * 3, 0, 0, 0, 61, 0, 0, 56, 57 * 3, 58 * 3, 0, 0, 0, 2, 0, 0, 40, 51 * 3, 62 * 3, 0, 0, 0, 48, 64 * 3, 63 * 3, 0, 49 * 3, 53 * 3, 0, 0, 0, 20, 0, 0, 12, 80 * 3, 83 * 3, 0, 0, 0, 63, 77 * 3, 75 * 3, 0, 65 * 3, 73 * 3, 0, 84 * 3, 66 * 3, 0, 0, 0, 24, 0, 0, 36, 0, 0, 3, 69 * 3, 87 * 3, 0, 81 * 3, 79 * 3, 0, 68 * 3, 71 * 3, 0, 70 * 3, 78 * 3, 0, 67 * 3, 76 * 3, 0, 72 * 3, 74 * 3, 0, 86 * 3, 85 * 3, 0, 88 * 3, 82 * 3, 0, -1, 94 * 3, 0, 95 * 3, 97 * 3, 0, 0, 0, 33, 0, 0, 9, 106 * 3, 110 * 3, 0, 102 * 3, 116 * 3, 0, 0, 0, 5, 0, 0, 10, 93 * 3, 89 * 3, 0, 0, 0, 6, 0, 0, 18, 0, 0, 17, 0, 0, 34, 113 * 3, 119 * 3, 0, 103 * 3, 104 * 3, 0, 90 * 3, 92 * 3, 0, 109 * 3, 107 * 3, 0, 117 * 3, 118 * 3, 0, 101 * 3, 99 * 3, 0, 98 * 3, 96 * 3, 0, 100 * 3, 91 * 3, 0, 114 * 3, 115 * 3, 0, 105 * 3, 108 * 3, 0, 112 * 3, 111 * 3, 0, 121 * 3, 125 * 3, 0, 0, 0, 41, 0, 0, 14, 0, 0, 21, 124 * 3, 122 * 3, 0, 120 * 3, 123 * 3, 0, 0, 0, 11, 0, 0, 19, 0, 0, 7, 0, 0, 35, 0, 0, 13, 0, 0, 50, 0, 0, 49, 0, 0, 58, 0, 0, 37, 0, 0, 25, 0, 0, 45, 0, 0, 57, 0, 0, 26, 0, 0, 29, 0, 0, 38, 0, 0, 53, 0, 0, 23, 0, 0, 43, 0, 0, 46, 0, 0, 42, 0, 0, 22, 0, 0, 54, 0, 0, 51, 0, 0, 15, 0, 0, 30, 0, 0, 39, 0, 0, 47, 0, 0, 55, 0, 0, 27, 0, 0, 59, 0, 0, 31]);
|
|
t.MOTION = new Int16Array([1 * 3, 2 * 3, 0, 4 * 3, 3 * 3, 0, 0, 0, 0, 6 * 3, 5 * 3, 0, 8 * 3, 7 * 3, 0, 0, 0, -1, 0, 0, 1, 9 * 3, 10 * 3, 0, 12 * 3, 11 * 3, 0, 0, 0, 2, 0, 0, -2, 14 * 3, 15 * 3, 0, 16 * 3, 13 * 3, 0, 20 * 3, 18 * 3, 0, 0, 0, 3, 0, 0, -3, 17 * 3, 19 * 3, 0, -1, 23 * 3, 0, 27 * 3, 25 * 3, 0, 26 * 3, 21 * 3, 0, 24 * 3, 22 * 3, 0, 32 * 3, 28 * 3, 0, 29 * 3, 31 * 3, 0, -1, 33 * 3, 0, 36 * 3, 35 * 3, 0, 0, 0, -4, 30 * 3, 34 * 3, 0, 0, 0, 4, 0, 0, -7, 0, 0, 5, 37 * 3, 41 * 3, 0, 0, 0, -5, 0, 0, 7, 38 * 3, 40 * 3, 0, 42 * 3, 39 * 3, 0, 0, 0, -6, 0, 0, 6, 51 * 3, 54 * 3, 0, 50 * 3, 49 * 3, 0, 45 * 3, 46 * 3, 0, 52 * 3, 47 * 3, 0, 43 * 3, 53 * 3, 0, 44 * 3, 48 * 3, 0, 0, 0, 10, 0, 0, 9, 0, 0, 8, 0, 0, -8, 57 * 3, 66 * 3, 0, 0, 0, -9, 60 * 3, 64 * 3, 0, 56 * 3, 61 * 3, 0, 55 * 3, 62 * 3, 0, 58 * 3, 63 * 3, 0, 0, 0, -10, 59 * 3, 65 * 3, 0, 0, 0, 12, 0, 0, 16, 0, 0, 13, 0, 0, 14, 0, 0, 11, 0, 0, 15, 0, 0, -16, 0, 0, -12, 0, 0, -14, 0, 0, -15, 0, 0, -11, 0, 0, -13]);
|
|
t.DCT_DC_SIZE_LUMINANCE = new Int8Array([2 * 3, 1 * 3, 0, 6 * 3, 5 * 3, 0, 3 * 3, 4 * 3, 0, 0, 0, 1, 0, 0, 2, 9 * 3, 8 * 3, 0, 7 * 3, 10 * 3, 0, 0, 0, 0, 12 * 3, 11 * 3, 0, 0, 0, 4, 0, 0, 3, 13 * 3, 14 * 3, 0, 0, 0, 5, 0, 0, 6, 16 * 3, 15 * 3, 0, 17 * 3, -1, 0, 0, 0, 7, 0, 0, 8]);
|
|
t.DCT_DC_SIZE_CHROMINANCE = new Int8Array([2 * 3, 1 * 3, 0, 4 * 3, 3 * 3, 0, 6 * 3, 5 * 3, 0, 8 * 3, 7 * 3, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 10 * 3, 9 * 3, 0, 0, 0, 3, 12 * 3, 11 * 3, 0, 0, 0, 4, 14 * 3, 13 * 3, 0, 0, 0, 5, 16 * 3, 15 * 3, 0, 0, 0, 6, 17 * 3, -1, 0, 0, 0, 7, 0, 0, 8]);
|
|
t.DCT_COEFF = new Int32Array([1 * 3, 2 * 3, 0, 4 * 3, 3 * 3, 0, 0, 0, 1, 7 * 3, 8 * 3, 0, 6 * 3, 5 * 3, 0, 13 * 3, 9 * 3, 0, 11 * 3, 10 * 3, 0, 14 * 3, 12 * 3, 0, 0, 0, 257, 20 * 3, 22 * 3, 0, 18 * 3, 21 * 3, 0, 16 * 3, 19 * 3, 0, 0, 0, 513, 17 * 3, 15 * 3, 0, 0, 0, 2, 0, 0, 3, 27 * 3, 25 * 3, 0, 29 * 3, 31 * 3, 0, 24 * 3, 26 * 3, 0, 32 * 3, 30 * 3, 0, 0, 0, 1025, 23 * 3, 28 * 3, 0, 0, 0, 769, 0, 0, 258, 0, 0, 1793, 0, 0, 65535, 0, 0, 1537, 37 * 3, 36 * 3, 0, 0, 0, 1281, 35 * 3, 34 * 3, 0, 39 * 3, 38 * 3, 0, 33 * 3, 42 * 3, 0, 40 * 3, 41 * 3, 0, 52 * 3, 50 * 3, 0, 54 * 3, 53 * 3, 0, 48 * 3, 49 * 3, 0, 43 * 3, 45 * 3, 0, 46 * 3, 44 * 3, 0, 0, 0, 2049, 0, 0, 4, 0, 0, 514, 0, 0, 2305, 51 * 3, 47 * 3, 0, 55 * 3, 57 * 3, 0, 60 * 3, 56 * 3, 0, 59 * 3, 58 * 3, 0, 61 * 3, 62 * 3, 0, 0, 0, 2561, 0, 0, 3329, 0, 0, 6, 0, 0, 259, 0, 0, 5, 0, 0, 770, 0, 0, 2817, 0, 0, 3073, 76 * 3, 75 * 3, 0, 67 * 3, 70 * 3, 0, 73 * 3, 71 * 3, 0, 78 * 3, 74 * 3, 0, 72 * 3, 77 * 3, 0, 69 * 3, 64 * 3, 0, 68 * 3, 63 * 3, 0, 66 * 3, 65 * 3, 0, 81 * 3, 87 * 3, 0, 91 * 3, 80 * 3, 0, 82 * 3, 79 * 3, 0, 83 * 3, 86 * 3, 0, 93 * 3, 92 * 3, 0, 84 * 3, 85 * 3, 0, 90 * 3, 94 * 3, 0, 88 * 3, 89 * 3, 0, 0, 0, 515, 0, 0, 260, 0, 0, 7, 0, 0, 1026, 0, 0, 1282, 0, 0, 4097, 0, 0, 3841, 0, 0, 3585, 105 * 3, 107 * 3, 0, 111 * 3, 114 * 3, 0, 104 * 3, 97 * 3, 0, 125 * 3, 119 * 3, 0, 96 * 3, 98 * 3, 0, -1, 123 * 3, 0, 95 * 3, 101 * 3, 0, 106 * 3, 121 * 3, 0, 99 * 3, 102 * 3, 0, 113 * 3, 103 * 3, 0, 112 * 3, 116 * 3, 0, 110 * 3, 100 * 3, 0, 124 * 3, 115 * 3, 0, 117 * 3, 122 * 3, 0, 109 * 3, 118 * 3, 0, 120 * 3, 108 * 3, 0, 127 * 3, 136 * 3, 0, 139 * 3, 140 * 3, 0, 130 * 3, 126 * 3, 0, 145 * 3, 146 * 3, 0, 128 * 3, 129 * 3, 0, 0, 0, 2050, 132 * 3, 134 * 3, 0, 155 * 3, 154 * 3, 0, 0, 0, 8, 137 * 3, 133 * 3, 0, 143 * 3, 144 * 3, 0, 151 * 3, 138 * 3, 0, 142 * 3, 141 * 3, 0, 0, 0, 10, 0, 0, 9, 0, 0, 11, 0, 0, 5377, 0, 0, 1538, 0, 0, 771, 0, 0, 5121, 0, 0, 1794, 0, 0, 4353, 0, 0, 4609, 0, 0, 4865, 148 * 3, 152 * 3, 0, 0, 0, 1027, 153 * 3, 150 * 3, 0, 0, 0, 261, 131 * 3, 135 * 3, 0, 0, 0, 516, 149 * 3, 147 * 3, 0, 172 * 3, 173 * 3, 0, 162 * 3, 158 * 3, 0, 170 * 3, 161 * 3, 0, 168 * 3, 166 * 3, 0, 157 * 3, 179 * 3, 0, 169 * 3, 167 * 3, 0, 174 * 3, 171 * 3, 0, 178 * 3, 177 * 3, 0, 156 * 3, 159 * 3, 0, 164 * 3, 165 * 3, 0, 183 * 3, 182 * 3, 0, 175 * 3, 176 * 3, 0, 0, 0, 263, 0, 0, 2562, 0, 0, 2306, 0, 0, 5633, 0, 0, 5889, 0, 0, 6401, 0, 0, 6145, 0, 0, 1283, 0, 0, 772, 0, 0, 13, 0, 0, 12, 0, 0, 14, 0, 0, 15, 0, 0, 517, 0, 0, 6657, 0, 0, 262, 180 * 3, 181 * 3, 0, 160 * 3, 163 * 3, 0, 196 * 3, 199 * 3, 0, 0, 0, 27, 203 * 3, 185 * 3, 0, 202 * 3, 201 * 3, 0, 0, 0, 19, 0, 0, 22, 197 * 3, 207 * 3, 0, 0, 0, 18, 191 * 3, 192 * 3, 0, 188 * 3, 190 * 3, 0, 0, 0, 20, 184 * 3, 194 * 3, 0, 0, 0, 21, 186 * 3, 193 * 3, 0, 0, 0, 23, 204 * 3, 198 * 3, 0, 0, 0, 25, 0, 0, 24, 200 * 3, 205 * 3, 0, 0, 0, 31, 0, 0, 30, 0, 0, 28, 0, 0, 29, 0, 0, 26, 0, 0, 17, 0, 0, 16, 189 * 3, 206 * 3, 0, 187 * 3, 195 * 3, 0, 218 * 3, 211 * 3, 0, 0, 0, 37, 215 * 3, 216 * 3, 0, 0, 0, 36, 210 * 3, 212 * 3, 0, 0, 0, 34, 213 * 3, 209 * 3, 0, 221 * 3, 222 * 3, 0, 219 * 3, 208 * 3, 0, 217 * 3, 214 * 3, 0, 223 * 3, 220 * 3, 0, 0, 0, 35, 0, 0, 267, 0, 0, 40, 0, 0, 268, 0, 0, 266, 0, 0, 32, 0, 0, 264, 0, 0, 265, 0, 0, 38, 0, 0, 269, 0, 0, 270, 0, 0, 33, 0, 0, 39, 0, 0, 7937, 0, 0, 6913, 0, 0, 7681, 0, 0, 4098, 0, 0, 7425, 0, 0, 7169, 0, 0, 271, 0, 0, 274, 0, 0, 273, 0, 0, 272, 0, 0, 1539, 0, 0, 2818, 0, 0, 3586, 0, 0, 3330, 0, 0, 3074, 0, 0, 3842]);
|
|
t.PICTURE_TYPE = {
|
|
INTRA: 1,
|
|
PREDICTIVE: 2,
|
|
B: 3
|
|
};
|
|
t.START = {
|
|
SEQUENCE: 179,
|
|
SLICE_FIRST: 1,
|
|
SLICE_LAST: 175,
|
|
PICTURE: 0,
|
|
EXTENSION: 181,
|
|
USER_DATA: 178
|
|
};
|
|
return t
|
|
}();
|
|
AMT.Renderer.WebGL = function() {
|
|
"use strict";
|
|
var t = function(e) {
|
|
this.canvas = e.canvas || document.createElement("canvas");
|
|
this.width = this.canvas.width;
|
|
this.height = this.canvas.height;
|
|
this.enabled = true;
|
|
var i = {
|
|
preserveDrawingBuffer: !! e.preserveDrawingBuffer,
|
|
alpha: false,
|
|
depth: false,
|
|
stencil: false,
|
|
antialias: false
|
|
};
|
|
this.gl = this.canvas.getContext("webgl", i) || this.canvas.getContext("experimental-webgl", i);
|
|
if (!this.gl) {
|
|
throw new Error("Failed to get WebGL Context")
|
|
}
|
|
var r = this.gl;
|
|
var s = null;
|
|
this.vertexBuffer = r.createBuffer();
|
|
var o = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);
|
|
r.bindBuffer(r.ARRAY_BUFFER, this.vertexBuffer);
|
|
r.bufferData(r.ARRAY_BUFFER, o, r.STATIC_DRAW);
|
|
this.program = this.createProgram(t.SHADER.VERTEX_IDENTITY, t.SHADER.FRAGMENT_YCRCB_TO_RGBA);
|
|
s = r.getAttribLocation(this.program, "vertex");
|
|
r.enableVertexAttribArray(s);
|
|
r.vertexAttribPointer(s, 2, r.FLOAT, false, 0, 0);
|
|
this.textureY = this.createTexture(0, "textureY");
|
|
this.textureCb = this.createTexture(1, "textureCb");
|
|
this.textureCr = this.createTexture(2, "textureCr");
|
|
this.loadingProgram = this.createProgram(t.SHADER.VERTEX_IDENTITY, t.SHADER.FRAGMENT_LOADING);
|
|
s = r.getAttribLocation(this.loadingProgram, "vertex");
|
|
r.enableVertexAttribArray(s);
|
|
r.vertexAttribPointer(s, 2, r.FLOAT, false, 0, 0);
|
|
this.shouldCreateUnclampedViews = !this.allowsClampedTextureData()
|
|
};
|
|
t.prototype.destroy = function() {
|
|
var t = this.gl;
|
|
t.deleteTexture(this.textureY);
|
|
t.deleteTexture(this.textureCb);
|
|
t.deleteTexture(this.textureCr);
|
|
t.deleteProgram(this.program);
|
|
t.deleteProgram(this.loadingProgram);
|
|
t.deleteBuffer(this.vertexBuffer)
|
|
};
|
|
t.prototype.resize = function(t, e) {
|
|
this.width = t | 0;
|
|
this.height = e | 0;
|
|
this.canvas.width = this.width;
|
|
this.canvas.height = this.height;
|
|
this.gl.useProgram(this.program);
|
|
this.gl.viewport(0, 0, this.width, this.height)
|
|
};
|
|
t.prototype.createTexture = function(t, e) {
|
|
var i = this.gl;
|
|
var r = i.createTexture();
|
|
i.bindTexture(i.TEXTURE_2D, r);
|
|
i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR);
|
|
i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR);
|
|
i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE);
|
|
i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE);
|
|
i.uniform1i(i.getUniformLocation(this.program, e), t);
|
|
return r
|
|
};
|
|
t.prototype.createProgram = function(t, e) {
|
|
var i = this.gl;
|
|
var r = i.createProgram();
|
|
i.attachShader(r, this.compileShader(i.VERTEX_SHADER, t));
|
|
i.attachShader(r, this.compileShader(i.FRAGMENT_SHADER, e));
|
|
i.linkProgram(r);
|
|
i.useProgram(r);
|
|
return r
|
|
};
|
|
t.prototype.compileShader = function(t, e) {
|
|
var i = this.gl;
|
|
var r = i.createShader(t);
|
|
i.shaderSource(r, e);
|
|
i.compileShader(r);
|
|
if (!i.getShaderParameter(r, i.COMPILE_STATUS)) {
|
|
throw new Error(i.getShaderInfoLog(r))
|
|
}
|
|
return r
|
|
};
|
|
t.prototype.allowsClampedTextureData = function() {
|
|
var t = this.gl;
|
|
var e = t.createTexture();
|
|
t.bindTexture(t.TEXTURE_2D, e);
|
|
t.texImage2D(t.TEXTURE_2D, 0, t.LUMINANCE, 1, 1, 0, t.LUMINANCE, t.UNSIGNED_BYTE, new Uint8ClampedArray([0]));
|
|
return t.getError() === 0
|
|
};
|
|
t.prototype.renderProgress = function(t) {
|
|
var e = this.gl;
|
|
e.useProgram(this.loadingProgram);
|
|
var i = e.getUniformLocation(this.loadingProgram, "progress");
|
|
e.uniform1f(i, t);
|
|
e.drawArrays(e.TRIANGLE_STRIP, 0, 4)
|
|
};
|
|
t.prototype.render = function(t, e, i) {
|
|
if (!this.enabled) {
|
|
return
|
|
}
|
|
var r = this.gl;
|
|
var s = this.width + 15 >> 4 << 4,
|
|
o = this.height,
|
|
h = s >> 1,
|
|
n = o >> 1;
|
|
if (this.shouldCreateUnclampedViews) {
|
|
t = new Uint8Array(t.buffer), e = new Uint8Array(e.buffer), i = new Uint8Array(i.buffer)
|
|
}
|
|
r.useProgram(this.program);
|
|
this.updateTexture(r.TEXTURE0, this.textureY, s, o, t);
|
|
this.updateTexture(r.TEXTURE1, this.textureCb, h, n, e);
|
|
this.updateTexture(r.TEXTURE2, this.textureCr, h, n, i);
|
|
r.drawArrays(r.TRIANGLE_STRIP, 0, 4)
|
|
};
|
|
t.prototype.updateTexture = function(t, e, i, r, s) {
|
|
var o = this.gl;
|
|
o.activeTexture(t);
|
|
o.bindTexture(o.TEXTURE_2D, e);
|
|
o.texImage2D(o.TEXTURE_2D, 0, o.LUMINANCE, i, r, 0, o.LUMINANCE, o.UNSIGNED_BYTE, s)
|
|
};
|
|
t.IsSupported = function() {
|
|
try {
|
|
if (!window.WebGLRenderingContext) {
|
|
return false
|
|
}
|
|
var t = document.createElement("canvas");
|
|
return !!(t.getContext("webgl") || t.getContext("experimental-webgl"))
|
|
} catch (t) {
|
|
return false
|
|
}
|
|
};
|
|
t.SHADER = {
|
|
FRAGMENT_YCRCB_TO_RGBA: ["precision mediump float;", "uniform sampler2D textureY;", "uniform sampler2D textureCb;", "uniform sampler2D textureCr;", "varying vec2 texCoord;", "mat4 rec601 = mat4(", "1.16438, 0.00000, 1.59603, -0.87079,", "1.16438, -0.39176, -0.81297, 0.52959,", "1.16438, 2.01723, 0.00000, -1.08139,", "0, 0, 0, 1", ");", "void main() {", "float y = texture2D(textureY, texCoord).r;", "float cb = texture2D(textureCb, texCoord).r;", "float cr = texture2D(textureCr, texCoord).r;", "gl_FragColor = vec4(y, cr, cb, 1.0) * rec601;", "}"].join("\n"),
|
|
FRAGMENT_LOADING: ["precision mediump float;", "uniform float progress;", "varying vec2 texCoord;", "void main() {", "float c = ceil(progress-(1.0-texCoord.y));", "gl_FragColor = vec4(c,c,c,1);", "}"].join("\n"),
|
|
VERTEX_IDENTITY: ["attribute vec2 vertex;", "varying vec2 texCoord;", "void main() {", "texCoord = vertex;", "gl_Position = vec4((vertex * 2.0 - 1.0) * vec2(1, -1), 0.0, 1.0);", "}"].join("\n")
|
|
};
|
|
return t
|
|
}();
|
|
AMT.Renderer.Canvas2D = function() {
|
|
"use strict";
|
|
var t = function(t) {
|
|
|
|
this.canvas = t.canvas || document.createElement("canvas");
|
|
this.width = this.canvas.width;
|
|
this.height = this.canvas.height;
|
|
this.enabled = true;
|
|
this.context = this.canvas.getContext("2d")
|
|
};
|
|
t.prototype.destroy = function() {};
|
|
t.prototype.resize = function(t, e) {
|
|
this.width = t | 0;
|
|
this.height = e | 0;
|
|
this.canvas.width = this.width;
|
|
this.canvas.height = this.height;
|
|
this.imageData = this.context.getImageData(0, 0, this.width, this.height);
|
|
AMT.Fill(this.imageData.data, 255)
|
|
};
|
|
t.prototype.renderProgress = function(t) {
|
|
var e = this.canvas.width,
|
|
i = this.canvas.height,
|
|
r = this.context;
|
|
r.fillStyle = "#222";
|
|
r.fillRect(0, 0, e, i);
|
|
r.fillStyle = "#fff";
|
|
r.fillRect(0, i - i * t, e, i * t)
|
|
};
|
|
t.prototype.render = function(t, e, i) {
|
|
this.YCbCrToRGBA(t, e, i, this.imageData.data);
|
|
this.context.putImageData(this.imageData, 0, 0)
|
|
};
|
|
t.prototype.YCbCrToRGBA = function(t, e, i, r) {
|
|
if (!this.enabled) {
|
|
return
|
|
}
|
|
var s = this.width + 15 >> 4 << 4,
|
|
o = s >> 1;
|
|
var h = 0,
|
|
n = s,
|
|
a = s + (s - this.width);
|
|
var d = 0,
|
|
c = o - (this.width >> 1);
|
|
var f = 0,
|
|
u = this.width * 4,
|
|
l = this.width * 4;
|
|
var p = this.width >> 1,
|
|
m = this.height >> 1;
|
|
var b, T, y, w, v;
|
|
for (var C = 0; C < m; C++) {
|
|
for (var A = 0; A < p; A++) {
|
|
b = e[d];
|
|
T = i[d];
|
|
d++;
|
|
y = b + (b * 103 >> 8) - 179;
|
|
w = (T * 88 >> 8) - 44 + (b * 183 >> 8) - 91;
|
|
v = T + (T * 198 >> 8) - 227;
|
|
var E = t[h++];
|
|
var g = t[h++];
|
|
r[f] = E + y;
|
|
r[f + 1] = E - w;
|
|
r[f + 2] = E + v;
|
|
r[f + 4] = g + y;
|
|
r[f + 5] = g - w;
|
|
r[f + 6] = g + v;
|
|
f += 8;
|
|
var R = t[n++];
|
|
var I = t[n++];
|
|
r[u] = R + y;
|
|
r[u + 1] = R - w;
|
|
r[u + 2] = R + v;
|
|
r[u + 4] = I + y;
|
|
r[u + 5] = I - w;
|
|
r[u + 6] = I + v;
|
|
u += 8
|
|
}
|
|
h += a;
|
|
n += a;
|
|
f += l;
|
|
u += l;
|
|
d += c
|
|
}
|
|
};
|
|
return t
|
|
}(); |