summaryrefslogtreecommitdiff
path: root/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-video.js
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-video.js')
-rw-r--r--extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-video.js317
1 files changed, 317 insertions, 0 deletions
diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-video.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-video.js
new file mode 100644
index 00000000..3afd769b
--- /dev/null
+++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-video.js
@@ -0,0 +1,317 @@
+(function() {
+ var global = this;
+
+ var scriptMap = {
+ OGVDemuxerOgg: 'ogv-demuxer-ogg.js',
+ OGVDemuxerWebM: 'ogv-demuxer-webm.js',
+ OGVDecoderAudioOpus: 'ogv-decoder-audio-opus.js',
+ OGVDecoderAudioVorbis: 'ogv-decoder-audio-vorbis.js',
+ OGVDecoderVideoTheora: 'ogv-decoder-video-theora.js',
+ OGVDecoderVideoVP8: 'ogv-decoder-video-vp8.js'
+ };
+
+ var proxyMap = {
+ OGVDecoderAudioOpus: 'OGVDecoderAudioProxy',
+ OGVDecoderAudioVorbis: 'OGVDecoderAudioProxy',
+ OGVDecoderVideoTheora: 'OGVDecoderVideoProxy',
+ OGVDecoderVideoVP8: 'OGVDecoderVideoProxy'
+ };
+ var workerMap = {
+ OGVDecoderAudioProxy: 'ogv-worker-audio.js',
+ OGVDecoderVideoProxy: 'ogv-worker-video.js'
+ };
+
+ function urlForClass(className) {
+ var scriptName = scriptMap[className];
+ if (scriptName) {
+ return urlForScript(scriptName);
+ } else {
+ throw new Error('asked for URL for unknown class ' + className);
+ }
+ };
+
+ function urlForScript(scriptName) {
+ if (scriptName) {
+ var base = OGVLoader.base;
+ if (base) {
+ base += '/';
+ }
+ return base + scriptName + '?version=' + encodeURIComponent(OGVVersion);
+ } else {
+ throw new Error('asked for URL for unknown script ' + scriptName);
+ }
+ };
+
+ var scriptStatus = {},
+ scriptCallbacks = {};
+ function loadWebScript(src, callback) {
+ if (scriptStatus[src] == 'done') {
+ callback();
+ } else if (scriptStatus[src] == 'loading') {
+ scriptCallbacks[src].push(callback);
+ } else {
+ scriptStatus[src] = 'loading';
+ scriptCallbacks[src] = [callback];
+
+ var scriptNode = document.createElement('script');
+ function done(event) {
+ var callbacks = scriptCallbacks[src];
+ delete scriptCallbacks[src];
+ scriptStatus[src] = 'done';
+
+ callbacks.forEach(function(cb) {
+ cb();
+ });
+ }
+ scriptNode.addEventListener('load', done);
+ scriptNode.addEventListener('error', done);
+ scriptNode.src = src;
+ document.querySelector('head').appendChild(scriptNode);
+ }
+ }
+
+ function defaultBase() {
+ if (typeof global.window === 'object') {
+
+ // for browser, try to autodetect
+ var scriptNodes = document.querySelectorAll('script'),
+ regex = /^(?:(.*)\/)ogv(?:-support)?\.js(?:\?|#|$)/,
+ path;
+ for (var i = 0; i < scriptNodes.length; i++) {
+ path = scriptNodes[i].getAttribute('src');
+ if (path) {
+ matches = path.match(regex);
+ if (matches) {
+ return matches[1];
+ }
+ }
+ }
+
+ } else {
+
+ // for workers, assume current directory
+ // if not a worker, too bad.
+ return '';
+
+ }
+ }
+
+ OGVLoader = {
+ base: defaultBase(),
+
+ loadClass: function(className, callback, options) {
+ options = options || {};
+ if (options.worker) {
+ this.workerProxy(className, callback);
+ } else if (typeof global[className] === 'function') {
+ // already loaded!
+ callback(global[className]);
+ } else if (typeof global.window === 'object') {
+ loadWebScript(urlForClass(className), function() {
+ callback(global[className]);
+ });
+ } else if (typeof global.importScripts === 'function') {
+ // worker has convenient sync importScripts
+ global.importScripts(urlForClass(className));
+ callback(global[className]);
+ }
+ },
+
+ workerProxy: function(className, callback) {
+ var proxyClass = proxyMap[className],
+ workerScript = workerMap[proxyClass];
+
+ if (!proxyClass) {
+ throw new Error('Requested worker for class with no proxy: ' + className);
+ }
+ if (!workerScript) {
+ throw new Error('Requested worker for class with no worker: ' + className);
+ }
+
+ this.loadClass(proxyClass, function(classObj) {
+ var construct = function(options) {
+ var worker = new Worker(urlForScript(workerScript));
+ return new classObj(worker, className, options);
+ };
+ callback(construct);
+ });
+ }
+ };
+})();
+/**
+ * Web Worker wrapper for codec fun
+ */
+function OGVWorkerSupport(propList, handlers) {
+
+ var transferables = (function() {
+ var buffer = new ArrayBuffer(1024),
+ bytes = new Uint8Array(buffer);
+ try {
+ postMessage({
+ action: 'transferTest',
+ bytes: bytes
+ }, [buffer]);
+ if (buffer.byteLength) {
+ // No transferable support
+ return false;
+ } else {
+ return true;
+ }
+ } catch (e) {
+ return false;
+ }
+ })();
+
+ var self = this;
+ self.target = null;
+
+ var sentProps = {};
+
+ function copyObject(obj) {
+ var copy = {};
+ for (var prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ copy[prop] = obj[prop];
+ }
+ }
+ return copy;
+ }
+
+ function copyAudioBuffer(data) {
+ if (data == null) {
+ return null;
+ } else {
+ // Array of Float32Arrays
+ var copy = [];
+ for (var i = 0; i < data.length; i++) {
+ copy[i] = new Float32Array(data[i]);
+ }
+ return copy;
+ }
+ }
+
+ function copyByteArray(bytes) {
+ var heap = bytes.buffer;
+ if (typeof heap.slice === 'function') {
+ var extract = heap.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
+ return new Uint8Array(extract);
+ } else {
+ // Hella slow in IE 10/11!
+ // But only game in town on IE 10.
+ return new Uint8Array(bytes);
+ }
+ }
+
+ function copyFrameBuffer(buffer) {
+ if (buffer == null) {
+ return null;
+ } else {
+ var copy = copyObject(buffer);
+ copy.bytesY = copyByteArray(buffer.bytesY);
+ copy.bytesCb = copyByteArray(buffer.bytesCb);
+ copy.bytesCr = copyByteArray(buffer.bytesCr);
+ return copy;
+ }
+ }
+
+ handlers.construct = function(args, callback) {
+ var className = args[0],
+ options = args[1];
+
+ OGVLoader.loadClass(className, function(classObj) {
+ self.target = new classObj(options);
+ callback();
+ });
+ };
+
+ addEventListener('message', function workerOnMessage(event) {
+ var data = event.data;
+
+ if (data && data.action == 'transferTest') {
+ // ignore
+ return;
+ }
+
+ if (typeof data !== 'object' || typeof data.action !== 'string' || typeof data.callbackId !== 'string' || typeof data.args !== 'object') {
+ console.log('invalid message data', data);
+ } else if (!(data.action in handlers)) {
+ console.log('invalid message action', data.action);
+ } else {
+ handlers[data.action].call(self, data.args, function(args) {
+ args = args || [];
+
+ // Collect and send any changed properties...
+ var props = {},
+ transfers = [];
+ propList.forEach(function(propName) {
+ var propVal = self.target[propName];
+
+ if (sentProps[propName] !== propVal) {
+ // Save this value for later reference...
+ sentProps[propName] = propVal;
+
+ if (propName == 'duration' && isNaN(propVal) && isNaN(sentProps[propName])) {
+ // NaN is not === itself. Nice!
+ // no need to update it here.
+ } else if (propName == 'audioBuffer') {
+ // Don't send the entire emscripten heap!
+ propVal = copyAudioBuffer(propVal);
+ props[propName] = propVal;
+ if (propVal) {
+ for (i = 0; i < propVal.length; i++) {
+ transfers.push(propVal[i].buffer);
+ }
+ }
+ } else if (propName == 'frameBuffer') {
+ // Don't send the entire emscripten heap!
+ propVal = copyFrameBuffer(propVal);
+ props[propName] = propVal;
+ if (propVal) {
+ transfers.push(propVal.bytesY.buffer);
+ transfers.push(propVal.bytesCb.buffer);
+ transfers.push(propVal.bytesCr.buffer);
+ }
+ } else {
+ props[propName] = propVal;
+ }
+ }
+ });
+
+ var out = {
+ action: 'callback',
+ callbackId: data.callbackId,
+ args: args,
+ props: props
+ };
+ if (transferables) {
+ postMessage(out, transfers);
+ } else {
+ postMessage(out);
+ }
+ });
+ }
+ });
+
+}
+proxy = new OGVWorkerSupport([
+ 'loadedMetadata',
+ 'videoFormat',
+ 'frameBuffer'
+], {
+ init: function(args, callback) {
+ this.target.init(callback);
+ },
+
+ processHeader: function(args, callback) {
+ this.target.processHeader(args[0], function(ok) {
+ callback([ok]);
+ });
+ },
+
+ processFrame: function(args, callback) {
+ this.target.processFrame(args[0], function(ok) {
+ callback([ok]);
+ });
+ }
+});
+this.OGVVersion = "1.0-20150904182230-dd3c8e8";