/camera/imageviewer

To get this branch, use:
bzr branch http://darksoft.org/webbzr/camera/imageviewer

« back to all changes in this revision

Viewing changes to cameralink/cameralink.c

  • Committer: Suren A. Chilingaryan
  • Date: 2011-02-13 01:34:55 UTC
  • Revision ID: csa@dside.dyndns.org-20110213013455-7999955h7v4uf9m8
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include "ruby.h"
 
3
 
 
4
#include "ds_log.h"
 
5
#include "cl.h"
 
6
 
 
7
#define BUFFER_FRAMES 16
 
8
 
 
9
static VALUE module_object;
 
10
static VALUE class_object;
 
11
 
 
12
struct TCameraLinkReader {
 
13
    CameraLink cl;
 
14
 
 
15
    VALUE str;
 
16
    
 
17
    int run_flag;
 
18
    int width, height;
 
19
    
 
20
    pid_t pid;
 
21
    int ready;
 
22
    int frame_id;
 
23
    void *data;
 
24
};
 
25
 
 
26
typedef struct TCameraLinkReader CameraLinkReader;
 
27
 
 
28
static void reader_mark(CameraLink *ctx) {
 
29
}
 
30
 
 
31
static VALUE reader_allocate(VALUE klass) {
 
32
    CameraLink *ctx = malloc(sizeof(CameraLinkReader));
 
33
    if (ctx) {
 
34
        memset(ctx, 0, sizeof(CameraLinkReader));
 
35
    } else {
 
36
        rb_raise(rb_eRuntimeError, "Allocation of CameraLink context is failed");
 
37
    }
 
38
    
 
39
    return Data_Wrap_Struct(klass, reader_mark, cl_destroy, ctx);
 
40
}
 
41
 
 
42
 
 
43
/*
 
44
static reader_callback(void *callback, int frame_id, void *data) {
 
45
    rb_funcall((VALUE)callback, rb_intern("call"), 2, INT2NUM(frame_id), Qnil);
 
46
}
 
47
*/
 
48
 
 
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));
 
51
}
 
52
 
 
53
static reader_callback(CameraLink *ctx, int frame_id, void *data) {
 
54
    struct RString *str = (struct RString*)((CameraLinkReader*)ctx)->str;
 
55
 
 
56
    char *ptr = str->ptr;
 
57
    str->ptr = data;
 
58
    rb_yield_values(2, INT2NUM(frame_id), (VALUE)str);
 
59
    str->ptr = ptr;
 
60
 
 
61
/*
 
62
        // This is a bit safer
 
63
    memcpy(str->ptr, data, ctx->width * ctx->height);
 
64
    rb_yield_values(2, INT2NUM(frame_id), str);
 
65
*/
 
66
 
 
67
    return 0;
 
68
}
 
69
 
 
70
static reader_thread_callback(CameraLinkReader *ctx, int frame_id, void *data) {
 
71
    while ((ctx->ready)&&(ctx->run_flag)) usleep(100);
 
72
    
 
73
    ctx->frame_id = frame_id;
 
74
    ctx->data = data;
 
75
    ctx->ready = 1;
 
76
}
 
77
 
 
78
 
 
79
static VALUE reader_init(VALUE self) {
 
80
    int err;
 
81
    CameraLink *ctx;
 
82
 
 
83
    Data_Get_Struct (self, CameraLink, ctx);
 
84
 
 
85
    err = cl_init(ctx);
 
86
    if (err) rb_raise(rb_eRuntimeError, "Initialization of CameraLink context is failed");
 
87
 
 
88
//    cl_register_frame_callback(ctx, &reader_callback, (void*)callback);
 
89
 
 
90
    return Qnil;
 
91
}
 
92
 
 
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];
 
98
 
 
99
    Data_Get_Struct (self, CameraLinkReader, ctx);
 
100
 
 
101
    cl_open((CameraLink*)ctx, width, height, 0);
 
102
    ctx->str = rb_str_new(tmp, width * height);
 
103
 
 
104
    return Qnil;
 
105
}
 
106
 
 
107
static VALUE reader_set_max_resolution(VALUE self, VALUE vWidth, VALUE vHeight) {
 
108
    CameraLink *ctx;
 
109
 
 
110
    Data_Get_Struct (self, CameraLink, ctx);
 
111
    cl_set_max_resolution((CameraLink*)ctx, NUM2INT(vWidth), NUM2INT(vHeight));
 
112
 
 
113
    return Qnil;
 
114
}
 
115
 
 
116
static VALUE reader_set_resolution(VALUE self, VALUE vWidth, VALUE vHeight) {
 
117
    CameraLink *ctx;
 
118
 
 
119
    Data_Get_Struct (self, CameraLink, ctx);
 
120
    cl_set_resolution((CameraLink*)ctx, NUM2INT(vWidth), NUM2INT(vHeight));
 
121
 
 
122
    return Qnil;
 
123
}
 
124
 
 
125
static VALUE reader_close(VALUE self) {
 
126
    CameraLink *ctx;
 
127
 
 
128
    Data_Get_Struct (self, CameraLink, ctx);
 
129
    cl_close(ctx);
 
130
 
 
131
    return Qnil;
 
132
}
 
133
 
 
134
static int *reader_run_thread(CameraLinkReader *ctx) {
 
135
    int err;
 
136
    err = cl_run_frames_continuous((CameraLink*)ctx, &ctx->run_flag, reader_thread_callback, ctx);
 
137
    return NULL;
 
138
}
 
139
 
 
140
static VALUE reader_sleep(VALUE delay) {
 
141
    return rb_funcall(Qnil, rb_intern("sleep"), 1, delay);
 
142
}
 
143
 
 
144
static VALUE reader_threaded_run(VALUE self, VALUE run_flag) {
 
145
    int err;
 
146
    void *res;
 
147
    VALUE delay;
 
148
    pthread_t thr;
 
149
 
 
150
    CameraLinkReader *ctx;
 
151
 
 
152
    rb_need_block();
 
153
    
 
154
    Data_Get_Struct (self, CameraLinkReader, ctx);
 
155
 
 
156
    ctx->pid = getpid();
 
157
    ctx->run_flag = 1;
 
158
 
 
159
    err = pthread_create(&thr, NULL, (void*(*)(void*))reader_run_thread,(void*)ctx);
 
160
    if (err) rb_raise(rb_eRuntimeError, "Thread scheduling is failed");
 
161
    
 
162
    delay = rb_float_new(0.001);        // better implement over socket, signal and exception are not really working
 
163
 
 
164
    while (ctx->run_flag) {
 
165
        if (ctx->ready) {
 
166
            //printf("In: %i %p\n", ctx->frame_id, ctx->data);
 
167
            reader_callback((CameraLink*)ctx, ctx->frame_id, ctx->data);
 
168
            ctx->ready = 0;
 
169
        }
 
170
        rb_funcall(Qnil, rb_intern("sleep"), 1, delay);
 
171
    }
 
172
    
 
173
    pthread_join(thr, &res);
 
174
 
 
175
    return Qnil;
 
176
}
 
177
 
 
178
static VALUE reader_run(VALUE self, VALUE run_flag) {
 
179
    int err;
 
180
 
 
181
    CameraLinkReader *ctx;
 
182
 
 
183
    rb_need_block();
 
184
    
 
185
    Data_Get_Struct (self, CameraLinkReader, ctx);
 
186
    
 
187
    ctx->run_flag = 1;
 
188
 
 
189
    err = cl_run_frames_continuous((CameraLink*)ctx, &ctx->run_flag, reader_callback, ctx);
 
190
    if (err) rb_raise(rb_eRuntimeError, "Run is failed");
 
191
 
 
192
    return Qnil;
 
193
}
 
194
 
 
195
static VALUE reader_safe_run(VALUE self, VALUE run_flag) {
 
196
    int err;
 
197
 
 
198
    CameraLinkReader *ctx;
 
199
 
 
200
    rb_need_block();
 
201
    
 
202
    Data_Get_Struct (self, CameraLinkReader, ctx);
 
203
 
 
204
    ctx->run_flag = 1;
 
205
 
 
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");
 
208
 
 
209
    return Qnil;
 
210
}
 
211
 
 
212
 
 
213
 
 
214
static VALUE reader_stop(VALUE self, VALUE run_flag) {
 
215
    int err;
 
216
    int rflag = 0;
 
217
 
 
218
    CameraLinkReader *ctx;
 
219
 
 
220
    Data_Get_Struct (self, CameraLinkReader, ctx);
 
221
 
 
222
    ctx->run_flag = 0;
 
223
    
 
224
    return Qnil;
 
225
}
 
226
 
 
227
 
 
228
void ds_raise_ruby_exception(int err, const char *msg) {
 
229
    rb_raise(rb_eRuntimeError, msg);
 
230
}
 
231
 
 
232
void Init_cameralink() {
 
233
 
 
234
    ds_log_configure_exception_handler(G_LOG_LEVEL_CRITICAL, ds_raise_ruby_exception, 0);
 
235
 
 
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);
 
248
}