7
#define BUFFER_FRAMES 16
9
static VALUE module_object;
10
static VALUE class_object;
12
struct TCameraLinkReader {
26
typedef struct TCameraLinkReader CameraLinkReader;
28
static void reader_mark(CameraLink *ctx) {
31
static VALUE reader_allocate(VALUE klass) {
32
CameraLink *ctx = malloc(sizeof(CameraLinkReader));
34
memset(ctx, 0, sizeof(CameraLinkReader));
36
rb_raise(rb_eRuntimeError, "Allocation of CameraLink context is failed");
39
return Data_Wrap_Struct(klass, reader_mark, cl_destroy, ctx);
44
static reader_callback(void *callback, int frame_id, void *data) {
45
rb_funcall((VALUE)callback, rb_intern("call"), 2, INT2NUM(frame_id), Qnil);
49
static reader_safe_callback(CameraLink *ctx, int frame_id, void *data) {
50
rb_yield_values(2, INT2NUM(frame_id), rb_str_new(data, ctx->width * ctx->height));
53
static reader_callback(CameraLink *ctx, int frame_id, void *data) {
54
struct RString *str = (struct RString*)((CameraLinkReader*)ctx)->str;
58
rb_yield_values(2, INT2NUM(frame_id), (VALUE)str);
62
// This is a bit safer
63
memcpy(str->ptr, data, ctx->width * ctx->height);
64
rb_yield_values(2, INT2NUM(frame_id), str);
70
static reader_thread_callback(CameraLinkReader *ctx, int frame_id, void *data) {
71
while ((ctx->ready)&&(ctx->run_flag)) usleep(100);
73
ctx->frame_id = frame_id;
79
static VALUE reader_init(VALUE self) {
83
Data_Get_Struct (self, CameraLink, ctx);
86
if (err) rb_raise(rb_eRuntimeError, "Initialization of CameraLink context is failed");
88
// cl_register_frame_callback(ctx, &reader_callback, (void*)callback);
93
static VALUE reader_open(VALUE self, VALUE vWidth, VALUE vHeight) {
94
CameraLinkReader *ctx;
95
int width = NUM2INT(vWidth);
96
int height = NUM2INT(vHeight);
97
char tmp[width*height];
99
Data_Get_Struct (self, CameraLinkReader, ctx);
101
cl_open((CameraLink*)ctx, width, height, 0);
102
ctx->str = rb_str_new(tmp, width * height);
107
static VALUE reader_set_max_resolution(VALUE self, VALUE vWidth, VALUE vHeight) {
110
Data_Get_Struct (self, CameraLink, ctx);
111
cl_set_max_resolution((CameraLink*)ctx, NUM2INT(vWidth), NUM2INT(vHeight));
116
static VALUE reader_set_resolution(VALUE self, VALUE vWidth, VALUE vHeight) {
119
Data_Get_Struct (self, CameraLink, ctx);
120
cl_set_resolution((CameraLink*)ctx, NUM2INT(vWidth), NUM2INT(vHeight));
125
static VALUE reader_close(VALUE self) {
128
Data_Get_Struct (self, CameraLink, ctx);
134
static int *reader_run_thread(CameraLinkReader *ctx) {
136
err = cl_run_frames_continuous((CameraLink*)ctx, &ctx->run_flag, reader_thread_callback, ctx);
140
static VALUE reader_sleep(VALUE delay) {
141
return rb_funcall(Qnil, rb_intern("sleep"), 1, delay);
144
static VALUE reader_threaded_run(VALUE self, VALUE run_flag) {
150
CameraLinkReader *ctx;
154
Data_Get_Struct (self, CameraLinkReader, ctx);
159
err = pthread_create(&thr, NULL, (void*(*)(void*))reader_run_thread,(void*)ctx);
160
if (err) rb_raise(rb_eRuntimeError, "Thread scheduling is failed");
162
delay = rb_float_new(0.001); // better implement over socket, signal and exception are not really working
164
while (ctx->run_flag) {
166
//printf("In: %i %p\n", ctx->frame_id, ctx->data);
167
reader_callback((CameraLink*)ctx, ctx->frame_id, ctx->data);
170
rb_funcall(Qnil, rb_intern("sleep"), 1, delay);
173
pthread_join(thr, &res);
178
static VALUE reader_run(VALUE self, VALUE run_flag) {
181
CameraLinkReader *ctx;
185
Data_Get_Struct (self, CameraLinkReader, ctx);
189
err = cl_run_frames_continuous((CameraLink*)ctx, &ctx->run_flag, reader_callback, ctx);
190
if (err) rb_raise(rb_eRuntimeError, "Run is failed");
195
static VALUE reader_safe_run(VALUE self, VALUE run_flag) {
198
CameraLinkReader *ctx;
202
Data_Get_Struct (self, CameraLinkReader, ctx);
206
err = cl_run_frames_continuous((CameraLink*)ctx, &ctx->run_flag, reader_safe_callback, ctx);
207
if (err) rb_raise(rb_eRuntimeError, "Run is failed");
214
static VALUE reader_stop(VALUE self, VALUE run_flag) {
218
CameraLinkReader *ctx;
220
Data_Get_Struct (self, CameraLinkReader, ctx);
228
void ds_raise_ruby_exception(int err, const char *msg) {
229
rb_raise(rb_eRuntimeError, msg);
232
void Init_cameralink() {
234
ds_log_configure_exception_handler(G_LOG_LEVEL_CRITICAL, ds_raise_ruby_exception, 0);
236
module_object = rb_define_module("CameraLink");
237
class_object = rb_define_class_under(module_object, "Reader", rb_cObject);
238
rb_define_alloc_func(class_object, reader_allocate);
239
rb_define_method(class_object, "initialize", reader_init, 0);
240
rb_define_method(class_object, "open", reader_open, 2);
241
rb_define_method(class_object, "close", reader_close, 0);
242
rb_define_method(class_object, "run", reader_run, 1);
243
rb_define_method(class_object, "safe_run", reader_safe_run, 1);
244
rb_define_method(class_object, "threaded_run", reader_threaded_run, 1);
245
rb_define_method(class_object, "stop", reader_stop, 0);
246
rb_define_method(class_object, "set_max_resolution", reader_set_max_resolution, 2);
247
rb_define_method(class_object, "set_resolution", reader_set_resolution, 2);