Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

builds and links for 32-bit and 64-bit on v8/Node 4.x #2

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added a.out
Binary file not shown.
11 changes: 0 additions & 11 deletions binding.gyp

This file was deleted.

1 change: 1 addition & 0 deletions binding.gyp
12 changes: 12 additions & 0 deletions binding_32.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"targets": [{
"target_name": "seret",
"sources": ["./src/camera.c", "./src/seret.cc"],
"cflags": ["-m32", "-Wall", "-Wextra", "-pedantic", "-ftrapv"],
"cflags_c": ["-std=c11", "-Wno-unused-parameter"],
"cflags_cc": ["-std=c++11"],
"libraries": ["/opt/libjpeg-turbo/lib32/libturbojpeg.a"],
"include_dirs" : ["/usr/include/nodejs/", "/opt/libjpeg-turbo/include/"]
}]
}

12 changes: 12 additions & 0 deletions binding_64.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"targets": [{
"target_name": "seret",
"sources": ["./src/camera.c", "./src/seret.cc"],
"cflags": ["-m64", "-Wall", "-Wextra", "-pedantic", "-ftrapv"],
"cflags_c": ["-std=c11", "-Wno-unused-parameter"],
"cflags_cc": ["-std=c++11"],
"libraries": ["/opt/libjpeg-turbo/lib64/libturbojpeg.a"],
"include_dirs" : ["/opt/libjpeg-turbo/include/"]
}]
}

10 changes: 10 additions & 0 deletions configure_x86_32.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
# this script should install everything you need to build for ubuntu (32bit)
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
sudo apt-get install -y build-essential nodejs node-gyp libc6-dev libc6-dev-i386 gcc-4.8-multilib g++-4.8-multilib gcc-4.9-multilib g++-4.9-multilib libv8
sudo npm install -g npm
sudo npm upgrade

# 32bit libjpegturbo
wget http://downloads.sourceforge.net/project/libjpeg-turbo/1.4.2/libjpeg-turbo-official_1.4.2_i386.deb
sudo dpkg -i libjpeg-turbo-official_1.4.2_i386.deb
11 changes: 11 additions & 0 deletions configure_x86_64.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
# this script should install everything you need to build for ubuntu (64bit)

curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
sudo apt-get install -y build-essential nodejs node-gyp libc6-dev libc6-dev-i386 gcc-4.8-multilib g++-4.8-multilib gcc-4.9-multilib g++-4.9-multilib libv8
sudo npm install -g npm
sudo npm upgrade

# 64bit libjpegturbo
wget http://downloads.sourceforge.net/project/libjpeg-turbo/1.4.2/libjpeg-turbo-official_1.4.2_amd64.deb
sudo dpkg -i libjpeg-turbo-official_1.4.2_amd64.deb
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"linux"
],
"dependencies": {
"async": "~0.9.0"
"async": "~0.9.0",
"nan": "^2.1.0"
}
}
64 changes: 42 additions & 22 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
# node-v4l2camera
# node-seret

Capturing images from USB(UVC) webcam on linux machines.

Notes by Angel Leon (January 2016):

I've made the module compatible with V8 4.x's new API on Jan 21st 2016.

I added `configure.sh` scripts for Ubuntu, both for 32 and 64 bits architectures.

If you want to build for 32bits, just point the symlinks of `binding.gyp` and `configure.sh` to their 32bit versions.

Then just do the following.

# do this once only to install dependencies
$ ./configure.sh

# and then this to build
$ npm install

If you want to build from a clean slate, just remove the generated build folder and invoke `npm install` again.

## Requirements

- node >= 0.10.x
- node == 0.10.33
- video4linux2 headers
- c and c++ compiler with `-std=c11` and `-std=c++11`
- gcc >= 4.7
Expand All @@ -14,23 +32,9 @@ Capturing images from USB(UVC) webcam on linux machines.
On linux machines:

```bash
npm install v4l2camera
```

- package details: https://npmjs.org/package/v4l2camera

## Usage

```js
var v4l2camera = require("v4l2camera");
'Pull the latest i386 build of libturbojpeg and install it'
http://sourceforge.net/projects/libjpeg-turbo/files/

var cam = new v4l2camera.Camera("/dev/video0");
cam.start();
cam.capture(function (success) {
var rgb = cam.toRGB();
require("fs").writeFileSync("result.raw", Buffer(rgb));
cam.stop();
});
```

For more detail see: examples/*.js (required "pngjs" or native "png" modules)
Expand Down Expand Up @@ -84,26 +88,42 @@ Control API
- `control.menu`: Array of items.
A control value is the index of the menu item when type is `"menu"`.

## Build for Development
## Build for Development (Updated September 2015)

On linux machines:

The instructions have been updated to ensure this module can be built as of September 1st, 2015.

```bash
'Ensure we use the correct V8 build version (Do Once)'
'Configuration fixes for libturbojpeg (Do Once)'
npm install -g n
n 0.10.33
sudo apt-get install libx32gcc-4.8-dev
sudo apt-get install libc6-dev-i386
sudo apt-get install linux-libc-dev:i386
sudo apt-get install gcc-4.9-multilib g++-4.9-multilib


cd myproject
mkdir -p node_modules
cd node_modules
git clone https://github.com/bellbind/node-v4l2camera.git v4l2camera
cd v4l2camera
git clone https://github.com/bitstopco/node-seret.git
cd node-seret
export CFLAGS='-m32'
export CXXFLAGS='-m32'
export LDFLAGS='-m32'
npm install
cd ../..
```

"build/Release/v4l2camera.node" is exist after the build.
"build/Release/seret.node" is exist after the build.

## Tested Environments

- Ubuntu raring armhf on BeagleBone Black with USB Buffalo BSW13K10H
- Ubuntu raring amd64 on Acer Aspire One with its screen facecam
- Mint linux i5 virtual machine on Lenovo Z570

## Notes

Expand Down
6 changes: 6 additions & 0 deletions src/camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ static void init_device(int fd, uint32_t width, uint32_t height, uint32_t fps)
}

CLEAR(cropcap);

cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {
Expand All @@ -298,6 +299,7 @@ static void init_device(int fd, uint32_t width, uint32_t height, uint32_t fps)
}

CLEAR(fmt);

fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = width;
fmt.fmt.pix.height = height;
Expand All @@ -308,6 +310,7 @@ static void init_device(int fd, uint32_t width, uint32_t height, uint32_t fps)
errno_exit("VIDIOC_S_FMT");

CLEAR(setfps);

setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
setfps.parm.capture.timeperframe.numerator = 1;
setfps.parm.capture.timeperframe.denominator = fps;
Expand Down Expand Up @@ -409,7 +412,9 @@ static int read_frame(int fd, char *result_buf, size_t result_size)
void control_set(int fd, uint32_t id, int32_t value)
{
struct v4l2_control control;

CLEAR(control);

control.id = id;
control.value = value;

Expand Down Expand Up @@ -441,6 +446,7 @@ int start_capturing(int fd)
struct v4l2_buffer buf;

CLEAR(buf);

buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
Expand Down
110 changes: 48 additions & 62 deletions src/seret.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <node.h>
#include <v8.h>
#include <node.h>
#include <node_buffer.h>

// C standard library
Expand All @@ -10,50 +10,49 @@
#include "camera.h"

using namespace v8;
using namespace node;

Handle<Value> CameraOn(const Arguments& args) {
HandleScope scope;
void throw_v8_exception(Isolate* isolate, const char* str) {
isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, str)));
}

void CameraOn(const FunctionCallbackInfo<v8::Value>& args) {
Isolate *isolate = args.GetIsolate();
HandleScope scope(isolate);

if (args.Length() != 4) {
return ThrowException(
Exception::TypeError(String::New("cameraOn requires 4 arguments"))
);
throw_v8_exception(isolate, "CameraOn() takes 4 arguments.");
return;
}

String::AsciiValue deviceString(args[0]->ToString());
String::Utf8Value deviceString(args[0]->ToString());
uint32_t width = args[1]->IntegerValue();
uint32_t height = args[2]->IntegerValue();
uint32_t fps = args[3]->IntegerValue();

int fd = camera_on(*deviceString, width, height, fps);

return scope.Close(Integer::New(fd));
args.GetReturnValue().Set(Integer::New(isolate, fd));
}

Handle<Value> CameraOff(const Arguments& args) {
HandleScope scope;
void CameraOff(const FunctionCallbackInfo<v8::Value>& args) {
Isolate *isolate = args.GetIsolate();
HandleScope scope(isolate);

if (args.Length() != 1) {
return ThrowException(
Exception::TypeError(String::New("cameraOff requires 1 argument"))
);
throw_v8_exception(isolate, "cameraOff requires 1 argument");
return;
}

int fd = args[0]->IntegerValue();

camera_off(fd);

return scope.Close(Null());
args.GetReturnValue().Set(Null(isolate));
}

Handle<Value> StartCapture(const Arguments& args) {
HandleScope scope;
void StartCapture(const FunctionCallbackInfo<v8::Value>& args) {
Isolate *isolate = args.GetIsolate();
HandleScope scope(isolate);

if (args.Length() != 1) {
return ThrowException(
Exception::TypeError(String::New("startCapture requires 1 argument"))
);
throw_v8_exception(isolate,"startCapture requires 1 argument");
return;
}

int fd = args[0]->IntegerValue();
Expand All @@ -64,32 +63,28 @@ Handle<Value> StartCapture(const Arguments& args) {
if (!success) stop_capturing(fd);
} while (!success);

return scope.Close(Null());
args.GetReturnValue().Set(Null(isolate));
}

Handle<Value> StopCapture(const Arguments& args) {
HandleScope scope;

void StopCapture(const FunctionCallbackInfo<v8::Value>& args) {
Isolate *isolate = args.GetIsolate();
HandleScope scope(isolate);
if (args.Length() != 1) {
return ThrowException(
Exception::TypeError(String::New("stopCapture requires 1 argument"))
);
throw_v8_exception(isolate, "stopCapture requires 1 argument");
return;
}

int fd = args[0]->IntegerValue();

stop_capturing(fd);

return scope.Close(Null());
args.GetReturnValue().Set(Null(isolate));
}

Handle<Value> CaptureFrame(const Arguments& args) {
HandleScope scope;
void CaptureFrame(const FunctionCallbackInfo<v8::Value>& args) {
Isolate *isolate = args.GetIsolate();
HandleScope scope(isolate);

if (args.Length() != 2) {
return ThrowException(
Exception::TypeError(String::New("captureFrame requires 2 arguments"))
);
throw_v8_exception(isolate, "captureframe requires 2 arguments");
return;
}

int fd = args[0]->IntegerValue();
Expand All @@ -99,42 +94,33 @@ Handle<Value> CaptureFrame(const Arguments& args) {
size_t bufferLength = node::Buffer::Length(buffer);
int result = capture_frame(fd, bufferData, bufferLength);

return scope.Close(Integer::New(result));
args.GetReturnValue().Set(Integer::New(isolate, result));
}

Handle<Value> ControlSet(const Arguments& args) {
HandleScope scope;
void ControlSet(const FunctionCallbackInfo<v8::Value>& args) {
Isolate *isolate = args.GetIsolate();
HandleScope scope(isolate);

if (args.Length() != 3) {
return ThrowException(
Exception::TypeError(String::New("captureFrame requires 3 arguments"))
);
throw_v8_exception(isolate, "controlSet requires 3 arguments");
return;
}

int fd = args[0]->IntegerValue();
uint32_t id = args[1]->Uint32Value();
int32_t value = args[2]->Int32Value();

control_set(fd, id, value);

return scope.Close(Null());
args.GetReturnValue().Set(Null(isolate));
}

void RegisterModule(Handle<Object> target) {

// target is the module object you see when require()ing the .node file.
target->Set(String::NewSymbol("cameraOn"),
FunctionTemplate::New(CameraOn)->GetFunction());
target->Set(String::NewSymbol("cameraOff"),
FunctionTemplate::New(CameraOff)->GetFunction());
target->Set(String::NewSymbol("startCapture"),
FunctionTemplate::New(StartCapture)->GetFunction());
target->Set(String::NewSymbol("stopCapture"),
FunctionTemplate::New(StopCapture)->GetFunction());
target->Set(String::NewSymbol("captureFrame"),
FunctionTemplate::New(CaptureFrame)->GetFunction());
target->Set(String::NewSymbol("controlSet"),
FunctionTemplate::New(ControlSet)->GetFunction());
NODE_SET_METHOD(target, "cameraOn" , CameraOn);
NODE_SET_METHOD(target, "cameraOff" , CameraOff);
NODE_SET_METHOD(target, "startCapture", StartCapture);
NODE_SET_METHOD(target, "stopCapture" , StopCapture);
NODE_SET_METHOD(target, "captureFrame", CaptureFrame);
NODE_SET_METHOD(target, "controlSet" , ControlSet);
}

NODE_MODULE(seret, RegisterModule)