node-opencv/src/VideoCaptureWrap.cc
2013-04-09 21:34:00 -07:00

130 lines
3.0 KiB
C++
Executable File

#include "VideoCaptureWrap.h"
#include "Matrix.h"
#include "OpenCV.h"
void AsyncRead(uv_work_t *req);
void AfterAsyncRead(uv_work_t *req);
v8::Persistent<FunctionTemplate> VideoCaptureWrap::constructor;
struct videocapture_baton {
Persistent<Function> cb;
VideoCaptureWrap *vc;
Matrix *im;
uv_work_t request;
};
void
VideoCaptureWrap::Init(Handle<Object> target) {
HandleScope scope;
// Constructor
constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(VideoCaptureWrap::New));
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->SetClassName(String::NewSymbol("VideoCapture"));
// Prototype
//Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
NODE_SET_PROTOTYPE_METHOD(constructor, "read", Read);
target->Set(String::NewSymbol("VideoCapture"), constructor->GetFunction());
};
Handle<Value>
VideoCaptureWrap::New(const Arguments &args) {
HandleScope scope;
if (args.This()->InternalFieldCount() == 0)
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new")));
VideoCaptureWrap *v;
if (args[0]->IsNumber()){
v = new VideoCaptureWrap(args[0]->NumberValue());
} else {
//TODO - assumes that we have string, verify
v = new VideoCaptureWrap(std::string(*v8::String::AsciiValue(args[0]->ToString())));
}
v->Wrap(args.This());
return args.This();
}
VideoCaptureWrap::VideoCaptureWrap(int device){
HandleScope scope;
cap.open(device);
if(!cap.isOpened()){
v8::ThrowException(v8::Exception::Error(String::New("Camera could not be opened")));
}
}
VideoCaptureWrap::VideoCaptureWrap(const std::string& filename){
HandleScope scope;
cap.open(filename);
// TODO! At the moment this only takes a full path - do relative too.
if(!cap.isOpened()){
v8::ThrowException(v8::Exception::Error(String::New("Video file could not be opened (opencv reqs. non relative paths)")));
}
}
Handle<Value>
VideoCaptureWrap::Read(const Arguments &args) {
HandleScope scope;
VideoCaptureWrap *v = ObjectWrap::Unwrap<VideoCaptureWrap>(args.This());
REQ_FUN_ARG(0, cb);
videocapture_baton *baton = new videocapture_baton();
baton->vc = v;
baton->cb = Persistent<Function>::New(cb);
baton->im = new Matrix();
baton->request.data = baton;
uv_queue_work(uv_default_loop(), &baton->request, AsyncRead, (uv_after_work_cb)AfterAsyncRead);
return Undefined();
}
void AsyncRead(uv_work_t *req) {
videocapture_baton *baton = static_cast<videocapture_baton *>(req->data);
baton->vc->cap.read(baton->im->mat);
}
void AfterAsyncRead(uv_work_t *req) {
HandleScope scope;
videocapture_baton *baton = static_cast<videocapture_baton *>(req->data);
Local<Object> im_to_return= Matrix::constructor->GetFunction()->NewInstance();
Matrix *img = ObjectWrap::Unwrap<Matrix>(im_to_return);
cv::Mat mat;
mat = baton->im->mat;
img->mat = mat;
Local<Value> argv[2];
argv[0] = Local<Value>::New(Null());
argv[1] = im_to_return;
baton->cb->Call(Context::GetCurrent()->Global(), 2, argv);
baton->cb.Dispose();
delete baton;
}