Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Commit

Permalink
* Adding video view for h264 frames to vehicle-view
Browse files Browse the repository at this point in the history
* Update to libcluon v0.0.102
* Update to OpenDLV Standard Message Set v0.9.5

Signed-off-by: Christian Berger <christian.berger@gu.se>
  • Loading branch information
chrberger committed Jul 3, 2018
1 parent d1a6dfb commit d4ec91b
Show file tree
Hide file tree
Showing 10 changed files with 4,491 additions and 51 deletions.
7 changes: 2 additions & 5 deletions Dockerfile.amd64
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

FROM alpine:3.7
FROM chalmersrevere/opendlv-ui-server-amd64:v0.0.9
MAINTAINER Christian Berger "christian.berger@gu.se"

RUN apk add libcluon --no-cache --repository https://chrberger.github.io/libcluon/alpine/v3.7 --allow-untrusted
RUN mkdir -p /opt/bin && wget -O /opt/bin/websocketd https://github.com/se-research/websocketd-alpine/raw/master/x86_64/websocketd && chmod 755 /opt/bin/websocketd
RUN mkdir /opt/vehicle-view
ADD src/ /opt/vehicle-view
ENTRYPOINT ["/opt/bin/websocketd", "--staticdir=/opt/vehicle-view", "--port=8081", "--binary=true", "/bin/cluon-OD4toStdout"]
ENTRYPOINT ["/usr/bin/opendlv-ui-server", "--http-root=/opt/vehicle-view", "--port=8081"]
20 changes: 2 additions & 18 deletions Dockerfile.armhf
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

FROM pipill/armhf-alpine:edge
FROM chalmersrevere/opendlv-ui-server-armhf:v0.0.9
MAINTAINER Christian Berger "christian.berger@gu.se"

RUN [ "cross-build-start" ]

RUN cat /etc/apk/repositories && \
echo http://dl-4.alpinelinux.org/alpine/v3.7/main > /etc/apk/repositories && \
echo http://dl-4.alpinelinux.org/alpine/v3.7/community >> /etc/apk/repositories && \
apk update && \
apk add wget && \
apk add libcluon --no-cache --repository https://chrberger.github.io/libcluon/alpine/v3.7 --allow-untrusted

RUN mkdir -p /opt/bin && wget -O /opt/bin/websocketd https://github.com/se-research/websocketd-alpine/raw/master/armhf/websocketd && chmod 755 /opt/bin/websocketd && apk del wget

RUN mkdir /opt/vehicle-view

RUN [ "cross-build-end" ]

ADD src/ /opt/vehicle-view

ENTRYPOINT ["/opt/bin/websocketd", "--staticdir=/opt/vehicle-view", "--port=8081", "--binary=true", "/bin/cluon-OD4toStdout"]
ENTRYPOINT ["/usr/bin/opendlv-ui-server", "--http-root=/opt/vehicle-view", "--port=8081"]
854 changes: 854 additions & 0 deletions src/Decoder.js

Large diffs are not rendered by default.

335 changes: 335 additions & 0 deletions src/Player.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,335 @@
/*
usage:
p = new Player({
useWorker: <bool>,
workerFile: <defaults to "Decoder.js"> // give path to Decoder.js
webgl: true | false | "auto" // defaults to "auto"
});
// canvas property represents the canvas node
// put it somewhere in the dom
p.canvas;
p.webgl; // contains the used rendering mode. if you pass auto to webgl you can see what auto detection resulted in
p.decode(<binary>);
*/



// universal module definition
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(["./Decoder", "./YUVCanvas"], factory);
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory(require("./Decoder"), require("./YUVCanvas"));
} else {
// Browser globals (root is window)
root.Player = factory(root.Decoder, root.YUVCanvas);
}
}(this, function (Decoder, WebGLCanvas) {
"use strict";


var nowValue = Decoder.nowValue;


var Player = function(parOptions){
var self = this;
this._config = parOptions || {};

this.render = true;
if (this._config.render === false){
this.render = false;
};

this.nowValue = nowValue;

this._config.workerFile = this._config.workerFile || "Decoder.js";
if (this._config.preserveDrawingBuffer){
this._config.contextOptions = this._config.contextOptions || {};
this._config.contextOptions.preserveDrawingBuffer = true;
};

var webgl = "auto";
if (this._config.webgl === true){
webgl = true;
}else if (this._config.webgl === false){
webgl = false;
};

if (webgl == "auto"){
webgl = true;
try{
if (!window.WebGLRenderingContext) {
// the browser doesn't even know what WebGL is
webgl = false;
} else {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("webgl");
if (!ctx) {
// browser supports WebGL but initialization failed.
webgl = false;
};
};
}catch(e){
webgl = false;
};
};

this.webgl = webgl;

// choose functions
if (this.webgl){
this.createCanvasObj = this.createCanvasWebGL;
this.renderFrame = this.renderFrameWebGL;
}else{
this.createCanvasObj = this.createCanvasRGB;
this.renderFrame = this.renderFrameRGB;
};


var lastWidth;
var lastHeight;
var onPictureDecoded = function(buffer, width, height, infos) {
self.onPictureDecoded(buffer, width, height, infos);

var startTime = nowValue();

if (!buffer || !self.render) {
return;
};

self.renderFrame({
canvasObj: self.canvasObj,
data: buffer,
width: width,
height: height
});

if (self.onRenderFrameComplete){
self.onRenderFrameComplete({
data: buffer,
width: width,
height: height,
infos: infos,
canvasObj: self.canvasObj
});
};

};

// provide size

if (!this._config.size){
this._config.size = {};
};
this._config.size.width = this._config.size.width || 200;
this._config.size.height = this._config.size.height || 200;

if (this._config.useWorker){
var worker = new Worker(this._config.workerFile);
this.worker = worker;
worker.addEventListener('message', function(e) {
var data = e.data;
if (data.consoleLog){
console.log(data.consoleLog);
return;
};

onPictureDecoded.call(self, new Uint8Array(data.buf, 0, data.length), data.width, data.height, data.infos);

}, false);

worker.postMessage({type: "Broadway.js - Worker init", options: {
rgb: !webgl,
memsize: this.memsize,
reuseMemory: this._config.reuseMemory ? true : false
}});

if (this._config.transferMemory){
this.decode = function(parData, parInfo){
// no copy
// instead we are transfering the ownership of the buffer
// dangerous!!!

worker.postMessage({buf: parData.buffer, offset: parData.byteOffset, length: parData.length, info: parInfo}, [parData.buffer]); // Send data to our worker.
};

}else{
this.decode = function(parData, parInfo){
// Copy the sample so that we only do a structured clone of the
// region of interest
var copyU8 = new Uint8Array(parData.length);
copyU8.set( parData, 0, parData.length );
worker.postMessage({buf: copyU8.buffer, offset: 0, length: parData.length, info: parInfo}, [copyU8.buffer]); // Send data to our worker.
};

};

if (this._config.reuseMemory){
this.recycleMemory = function(parArray){
//this.beforeRecycle();
worker.postMessage({reuse: parArray.buffer}, [parArray.buffer]); // Send data to our worker.
//this.afterRecycle();
};
}

}else{

this.decoder = new Decoder({
rgb: !webgl
});
this.decoder.onPictureDecoded = onPictureDecoded;

this.decode = function(parData, parInfo){
self.decoder.decode(parData, parInfo);
};

};



if (this.render){
this.canvasObj = this.createCanvasObj({
contextOptions: this._config.contextOptions
});
this.canvas = this.canvasObj.canvas;
};

this.domNode = this.canvas;

lastWidth = this._config.size.width;
lastHeight = this._config.size.height;

};

Player.prototype = {

onPictureDecoded: function(buffer, width, height, infos){},

// call when memory of decoded frames is not used anymore
recycleMemory: function(buf){
},
/*beforeRecycle: function(){},
afterRecycle: function(){},*/

// for both functions options is:
//
// width
// height
// enableScreenshot
//
// returns a object that has a property canvas which is a html5 canvas
createCanvasWebGL: function(options){
var canvasObj = this._createBasicCanvasObj(options);
canvasObj.contextOptions = options.contextOptions;
return canvasObj;
},

createCanvasRGB: function(options){
var canvasObj = this._createBasicCanvasObj(options);
return canvasObj;
},

// part that is the same for webGL and RGB
_createBasicCanvasObj: function(options){
options = options || {};

var obj = {};
var width = options.width;
if (!width){
width = this._config.size.width;
};
var height = options.height;
if (!height){
height = this._config.size.height;
};
obj.canvas = document.createElement('canvas');
obj.canvas.width = width;
obj.canvas.height = height;
obj.canvas.style.backgroundColor = "#0D0E1B";


return obj;
},

// options:
//
// canvas
// data
renderFrameWebGL: function(options){

var canvasObj = options.canvasObj;

var width = options.width || canvasObj.canvas.width;
var height = options.height || canvasObj.canvas.height;

if (canvasObj.canvas.width !== width || canvasObj.canvas.height !== height || !canvasObj.webGLCanvas){
canvasObj.canvas.width = width;
canvasObj.canvas.height = height;
canvasObj.webGLCanvas = new WebGLCanvas({
canvas: canvasObj.canvas,
contextOptions: canvasObj.contextOptions,
width: width,
height: height
});
};

var ylen = width * height;
var uvlen = (width / 2) * (height / 2);

canvasObj.webGLCanvas.drawNextOutputPicture({
yData: options.data.subarray(0, ylen),
uData: options.data.subarray(ylen, ylen + uvlen),
vData: options.data.subarray(ylen + uvlen, ylen + uvlen + uvlen)
});

var self = this;
self.recycleMemory(options.data);

},
renderFrameRGB: function(options){
var canvasObj = options.canvasObj;

var width = options.width || canvasObj.canvas.width;
var height = options.height || canvasObj.canvas.height;

if (canvasObj.canvas.width !== width || canvasObj.canvas.height !== height){
canvasObj.canvas.width = width;
canvasObj.canvas.height = height;
};

var ctx = canvasObj.ctx;
var imgData = canvasObj.imgData;

if (!ctx){
canvasObj.ctx = canvasObj.canvas.getContext('2d');
ctx = canvasObj.ctx;

canvasObj.imgData = ctx.createImageData(width, height);
imgData = canvasObj.imgData;
};

imgData.data.set(options.data);
ctx.putImageData(imgData, 0, 0);
var self = this;
self.recycleMemory(options.data);

}

};

return Player;

}));

Loading

0 comments on commit d4ec91b

Please sign in to comment.