wiretap 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +32 -0
- data/README +93 -0
- data/ext/Makefile +146 -0
- data/ext/audio_format.cpp +224 -0
- data/ext/bmp.cpp +65 -0
- data/ext/extconf.rb +85 -0
- data/ext/format.cpp +347 -0
- data/ext/image.h +27 -0
- data/ext/image_format.cpp +194 -0
- data/ext/node.cpp +401 -0
- data/ext/nodechildren.cpp +67 -0
- data/ext/nodeframes.cpp +233 -0
- data/ext/nodemetadata.cpp +90 -0
- data/ext/ppm.cpp +132 -0
- data/ext/server.cpp +202 -0
- data/ext/serverlist.cpp +183 -0
- data/ext/sgi.cpp +69 -0
- data/ext/testserver/Makefile +5 -0
- data/ext/testserver/cfg/wiretap_path_translation_db.xml +44 -0
- data/ext/testserver/cfg/wiretapd.cfg +74 -0
- data/ext/testserver/cfg/wiretapd.res +60 -0
- data/ext/testserver/db.sql +50 -0
- data/ext/testserver/server.cpp +206 -0
- data/ext/testserver/testserver.rb +146 -0
- data/ext/thread_worker.cpp +85 -0
- data/ext/wiretap.cpp +68 -0
- data/ext/wiretap.h +115 -0
- data/lib/wiretap.rb +280 -0
- data/test/audio.rb +27 -0
- data/test/convert.rb +35 -0
- data/test/image.rb +101 -0
- data/test/read_frames.rb +142 -0
- data/test/wiretap-images/01.ppm +0 -0
- data/test/wiretap-images/32bit.stoneimage +621 -0
- data/test/wiretap-images/36bit.stoneimage +1036 -0
- data/test/wiretap-images/48bit.stoneimage +800 -1
- data/test/wiretap-images/a.stoneimage +0 -0
- data/test/wiretap-images/a0.stoneimage +0 -0
- data/test/wiretap-images/a1.stoneimage +0 -0
- data/test/wiretap-images/a2.stoneimage +0 -0
- data/test/wiretap-images/a3.stoneimage +0 -0
- data/test/wiretap-images/a4.stoneimage +0 -0
- data/test/wiretap-images/b1.stonesound +0 -0
- data/test/wiretap-images/importable-seq/00000001.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000002.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000003.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000004.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000005.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000006.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000007.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000008.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000009.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000010.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000011.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000012.ppm +0 -0
- data/test/wiretap-images/monsters_001.tif +0 -0
- data/test/wiretap-images/monsters_002.tif +0 -0
- data/test/wiretap-images/monsters_003.tif +0 -0
- data/test/wiretap-images/output.mov +0 -0
- data/test/wiretap-images/output.wav +0 -0
- data/test/write_frames.rb +82 -0
- metadata +138 -0
data/ext/node.cpp
ADDED
@@ -0,0 +1,401 @@
|
|
1
|
+
#include "wiretap.h"
|
2
|
+
|
3
|
+
|
4
|
+
static void node_free(WireTapNodeHandle* node) {
|
5
|
+
delete node;
|
6
|
+
}
|
7
|
+
|
8
|
+
static void node_leave(WireTapNodeHandle* node) {
|
9
|
+
}
|
10
|
+
|
11
|
+
static VALUE node_detect_klass(WireTapNodeHandle* node) {
|
12
|
+
int type;
|
13
|
+
NODERUN_E(node, node->getNodeType(type));
|
14
|
+
switch(type) {
|
15
|
+
case IFFFS_WT_TYPE_NODE: {
|
16
|
+
return cNode;
|
17
|
+
}
|
18
|
+
case IFFFS_WT_TYPE_HOST: {
|
19
|
+
return cHost;
|
20
|
+
}
|
21
|
+
case IFFFS_WT_TYPE_VOLUME: {
|
22
|
+
return cVolume;
|
23
|
+
}
|
24
|
+
case IFFFS_WT_TYPE_PROJECT: {
|
25
|
+
return cProject;
|
26
|
+
}
|
27
|
+
case IFFFS_WT_TYPE_LIBRARY: {
|
28
|
+
return cLibrary;
|
29
|
+
}
|
30
|
+
case IFFFS_WT_TYPE_REEL: {
|
31
|
+
return cReel;
|
32
|
+
}
|
33
|
+
case IFFFS_WT_TYPE_CLIP:
|
34
|
+
case IFFFS_WT_TYPE_CLIP_HIRES:
|
35
|
+
case IFFFS_WT_TYPE_CLIP_LOWRES:
|
36
|
+
case IFFFS_WT_TYPE_CLIP_SLATE: {
|
37
|
+
return cClip;
|
38
|
+
}
|
39
|
+
case IFFFS_WT_TYPE_CLIP_AUDIO:
|
40
|
+
case IFFFS_WT_TYPE_CLIP_AUDIO_STREAM: {
|
41
|
+
return cAudio;
|
42
|
+
}
|
43
|
+
case IFFFS_WT_TYPE_USER:
|
44
|
+
case IFFFS_WT_TYPE_SETUP:
|
45
|
+
case IFFFS_WT_TYPE_USER_PREFERENCE: {
|
46
|
+
}
|
47
|
+
}
|
48
|
+
return cNode;
|
49
|
+
}
|
50
|
+
|
51
|
+
VALUE wiretap_node_create_with(WireTapNodeHandle& node, VALUE server, VALUE parent) {
|
52
|
+
WireTapNodeHandle* new_node = new WireTapNodeHandle(node);
|
53
|
+
|
54
|
+
VALUE created_node = Data_Wrap_Struct(node_detect_klass(new_node), 0, node_free, new_node);
|
55
|
+
rb_iv_set(created_node, "@server", server);
|
56
|
+
rb_iv_set(created_node, "@parent", parent);
|
57
|
+
return created_node;
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
static VALUE wiretap_node_allocate(VALUE klass) {
|
62
|
+
WireTapNodeHandle* new_node = new WireTapNodeHandle();
|
63
|
+
return Data_Wrap_Struct(klass, 0, node_free, new_node);
|
64
|
+
}
|
65
|
+
|
66
|
+
static VALUE wiretap_node_get_id(VALUE self) {
|
67
|
+
Check_Node_Alive(self);
|
68
|
+
|
69
|
+
WireTapNodeHandle* node;
|
70
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
71
|
+
return rb_str_new2(node->getNodeId().id());
|
72
|
+
}
|
73
|
+
|
74
|
+
static VALUE wiretap_node_set_id(VALUE self, VALUE id) {
|
75
|
+
Check_Node_Alive(self);
|
76
|
+
|
77
|
+
WireTapNodeHandle* node;
|
78
|
+
Check_Type(id, T_STRING);
|
79
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
80
|
+
// node->setNodeId(WireTapNodeId(STR(id)));
|
81
|
+
return self;
|
82
|
+
}
|
83
|
+
|
84
|
+
static VALUE wiretap_node_reload(VALUE self) {
|
85
|
+
Check_Node_Alive(self);
|
86
|
+
|
87
|
+
WireTapNodeHandle* node;
|
88
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
89
|
+
WireTapNodeId id = node->getNodeId();
|
90
|
+
WireTapServerHandle server = node->getServer();
|
91
|
+
delete node;
|
92
|
+
*((WireTapNodeHandle **)&(RDATA(self)->data)) = new WireTapNodeHandle(server, id.id());
|
93
|
+
return self;
|
94
|
+
}
|
95
|
+
|
96
|
+
static VALUE wiretap_node_find(VALUE self, VALUE path) {
|
97
|
+
Check_Node_Alive(self);
|
98
|
+
|
99
|
+
WireTapNodeHandle* node;
|
100
|
+
Check_Type(path, T_STRING);
|
101
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
102
|
+
|
103
|
+
if(LEN(path) == 0) {
|
104
|
+
return self;
|
105
|
+
}
|
106
|
+
WireTapNodeHandle child;
|
107
|
+
if(!WireTapFindChild(*node, CSTR(path), child)) {
|
108
|
+
if(!node->lastError() || !*node->lastError()) {
|
109
|
+
return Qnil;
|
110
|
+
}
|
111
|
+
rb_raise(eError, "Problem while looking for child '%s': %s", CSTR(path), node->lastError());
|
112
|
+
}
|
113
|
+
|
114
|
+
return wiretap_node_create_with(child, rb_iv_get(self, "@server"), self);
|
115
|
+
}
|
116
|
+
|
117
|
+
|
118
|
+
static VALUE wiretap_clip_import_directory(VALUE self, VALUE dir_name) {
|
119
|
+
Check_Node_Alive(self);
|
120
|
+
|
121
|
+
Check_Type(dir_name, T_STRING);
|
122
|
+
|
123
|
+
WireTapNodeHandle* node;
|
124
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
125
|
+
|
126
|
+
int count = 0;
|
127
|
+
struct stat sb;
|
128
|
+
/*
|
129
|
+
* Mplayer decoding video always start writing frame from 00000001.ppm
|
130
|
+
*/
|
131
|
+
for(int i = 1;; i++) {
|
132
|
+
char filename[PATH_MAX];
|
133
|
+
snprintf(filename, sizeof(filename), "%s/%08d.ppm", STR(dir_name), i);
|
134
|
+
if(stat(filename, &sb) != 0) {
|
135
|
+
break;
|
136
|
+
}
|
137
|
+
count = i;
|
138
|
+
}
|
139
|
+
|
140
|
+
if(count <= 0) {
|
141
|
+
return Qnil;
|
142
|
+
}
|
143
|
+
|
144
|
+
|
145
|
+
NODERUN_E(node, node->setNumFrames(count));
|
146
|
+
WireTapClipFormat format;
|
147
|
+
NODERUN_E(node, node->getClipFormat(format));
|
148
|
+
unsigned char frame[format.frameBufferSize()];
|
149
|
+
|
150
|
+
/** TODO - refactor to use write_frame **/
|
151
|
+
|
152
|
+
for(int i = 0; i < count; i++) {
|
153
|
+
char filename[PATH_MAX];
|
154
|
+
snprintf(filename, sizeof(filename), "%s/%08d.ppm", STR(dir_name), i+1);
|
155
|
+
//rb_warn("Opening file %s", filename);
|
156
|
+
|
157
|
+
|
158
|
+
FILE* infile = fopen(filename, "r");
|
159
|
+
if(!infile) {
|
160
|
+
THROW("Couldn't open file %s for read", filename);
|
161
|
+
}
|
162
|
+
|
163
|
+
if(!ppm_read_format(infile, NULL)) {
|
164
|
+
fclose(infile);
|
165
|
+
THROW("Couldn't read PPM format from file %s", filename);
|
166
|
+
}
|
167
|
+
|
168
|
+
if(!ppm_read_image(infile, frame, format.width(), format.height(), format.bitsPerPixel())) {
|
169
|
+
fclose(infile);
|
170
|
+
rb_warn("Couldn't read PPM image data from file %s", filename);
|
171
|
+
return Qnil;
|
172
|
+
}
|
173
|
+
fclose(infile);
|
174
|
+
|
175
|
+
NODERUN_E(node, node->writeFrame(i, frame, sizeof(frame)));
|
176
|
+
}
|
177
|
+
return self;
|
178
|
+
}
|
179
|
+
|
180
|
+
static VALUE wiretap_node_get_type(VALUE self) {
|
181
|
+
Check_Node_Alive(self);
|
182
|
+
|
183
|
+
WireTapNodeHandle* node;
|
184
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
185
|
+
WireTapStr type;
|
186
|
+
NODERUN_E(node, node->getNodeTypeStr(type));
|
187
|
+
return wiretap_to_str(type);
|
188
|
+
}
|
189
|
+
|
190
|
+
static VALUE wiretap_node_get_name(VALUE self) {
|
191
|
+
Check_Node_Alive(self);
|
192
|
+
|
193
|
+
WireTapNodeHandle* node;
|
194
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
195
|
+
WireTapStr name;
|
196
|
+
NODERUN_E(node, node->getDisplayName(name));
|
197
|
+
return wiretap_to_str(name);
|
198
|
+
}
|
199
|
+
|
200
|
+
|
201
|
+
static VALUE wiretap_node_create_node(int argc, VALUE* argv, VALUE self) {
|
202
|
+
Check_Node_Alive(self);
|
203
|
+
|
204
|
+
WireTapNodeHandle* node;
|
205
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
206
|
+
VALUE display_name, extended_type;
|
207
|
+
|
208
|
+
rb_scan_args(argc, argv, "11", &display_name, &extended_type);
|
209
|
+
Check_Type(display_name, T_STRING);
|
210
|
+
WireTapNodeHandle node_return;
|
211
|
+
|
212
|
+
if(extended_type == Qnil) {
|
213
|
+
extended_type = INT2FIX(0);
|
214
|
+
}
|
215
|
+
switch(TYPE(extended_type)) {
|
216
|
+
case T_FIXNUM:
|
217
|
+
NODERUN_E(node, node->createNode(CSTR(display_name), NUM2INT(extended_type), node_return));
|
218
|
+
break;
|
219
|
+
case T_STRING:
|
220
|
+
NODERUN_E(node, node->createNode(CSTR(display_name), CSTR(extended_type), node_return));
|
221
|
+
break;
|
222
|
+
default:
|
223
|
+
rb_raise(rb_eArgError, "extended type must be integer or string");
|
224
|
+
}
|
225
|
+
|
226
|
+
return wiretap_node_create_with(node_return, rb_iv_get(self, "@server"), self);
|
227
|
+
}
|
228
|
+
|
229
|
+
|
230
|
+
static VALUE wiretap_node_create_clip(int argc, VALUE* argv, VALUE self) {
|
231
|
+
WireTapNodeHandle* node;
|
232
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
233
|
+
VALUE display_name, extended_type, format;
|
234
|
+
|
235
|
+
Check_Node_Alive(self);
|
236
|
+
|
237
|
+
rb_scan_args(argc, argv, "12", &display_name, &extended_type, &format);
|
238
|
+
Check_Type(display_name, T_STRING);
|
239
|
+
WireTapNodeHandle node_return;
|
240
|
+
|
241
|
+
if(extended_type == Qnil) {
|
242
|
+
extended_type = INT2FIX(0);
|
243
|
+
}
|
244
|
+
if(format == Qnil) {
|
245
|
+
format = rb_funcall(self, rb_intern("format"), 0);
|
246
|
+
}
|
247
|
+
|
248
|
+
WireTapClipFormat *f;
|
249
|
+
Data_Get_Struct(format, WireTapClipFormat, f);
|
250
|
+
|
251
|
+
switch(TYPE(extended_type)) {
|
252
|
+
case T_FIXNUM:
|
253
|
+
NODERUN_E(node, node->createClipNode(CSTR(display_name), *f, NUM2INT(extended_type), node_return));
|
254
|
+
break;
|
255
|
+
case T_STRING:
|
256
|
+
NODERUN_E(node, node->createClipNode(CSTR(display_name), *f, CSTR(extended_type), node_return));
|
257
|
+
break;
|
258
|
+
default:
|
259
|
+
rb_raise(rb_eArgError, "extended type must be integer or string");
|
260
|
+
}
|
261
|
+
|
262
|
+
return wiretap_node_create_with(node_return, rb_iv_get(self, "@server"), self);
|
263
|
+
}
|
264
|
+
|
265
|
+
|
266
|
+
static VALUE wiretap_node_destroy(VALUE self) {
|
267
|
+
WireTapNodeHandle* node;
|
268
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
269
|
+
NODERUN_E(node, node->destroyNode());
|
270
|
+
rb_iv_set(self, "@destroyed", Qtrue);
|
271
|
+
return Qtrue;
|
272
|
+
}
|
273
|
+
|
274
|
+
|
275
|
+
|
276
|
+
/*
|
277
|
+
* Extract metadata from node
|
278
|
+
* @node.metadata
|
279
|
+
*/
|
280
|
+
static VALUE wiretap_node_metadata(VALUE self) {
|
281
|
+
Check_Node_Alive(self);
|
282
|
+
|
283
|
+
WireTapNodeHandle* node;
|
284
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
285
|
+
VALUE metadata = Data_Wrap_Struct(cNodeMetaData, 0, node_leave, node);
|
286
|
+
rb_iv_set(metadata, "@node", self);
|
287
|
+
|
288
|
+
/*
|
289
|
+
WireTapStr metaDataBody; <--- !
|
290
|
+
node->getMetaData(streamName, filter, depth)
|
291
|
+
plainly speaking - somehow this has to happen, all that schtuff
|
292
|
+
*/
|
293
|
+
|
294
|
+
return metadata;
|
295
|
+
}
|
296
|
+
|
297
|
+
|
298
|
+
|
299
|
+
static VALUE wiretap_clip_format(VALUE self) {
|
300
|
+
Check_Node_Alive(self);
|
301
|
+
|
302
|
+
WireTapNodeHandle* node;
|
303
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
304
|
+
WireTapClipFormat format;
|
305
|
+
NODERUN_E(node, node->getClipFormat(format));
|
306
|
+
VALUE clipformat = Data_Wrap_Struct(cClipFormat, 0, wiretap_format_free, new WireTapClipFormat(format));
|
307
|
+
rb_iv_set(clipformat, "@node", self);
|
308
|
+
return clipformat;
|
309
|
+
}
|
310
|
+
|
311
|
+
|
312
|
+
static VALUE wiretap_audio_format(VALUE self) {
|
313
|
+
Check_Node_Alive(self);
|
314
|
+
|
315
|
+
WireTapNodeHandle* node;
|
316
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
317
|
+
WireTapAudioFormat audio_format;
|
318
|
+
NODERUN_E(node, node->getClipFormat(audio_format));
|
319
|
+
VALUE audioformat = Data_Wrap_Struct(cAudioFormat, 0, wiretap_format_free, new WireTapAudioFormat(audio_format));
|
320
|
+
rb_iv_set(audioformat, "@node", self);
|
321
|
+
return audioformat;
|
322
|
+
}
|
323
|
+
|
324
|
+
|
325
|
+
static VALUE wiretap_clip_frames(VALUE self) {
|
326
|
+
Check_Node_Alive(self);
|
327
|
+
|
328
|
+
WireTapNodeHandle* node;
|
329
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
330
|
+
VALUE frames = Data_Wrap_Struct(cNodeFrames, 0, node_leave, node);
|
331
|
+
rb_iv_set(frames, "@node", self);
|
332
|
+
return frames;
|
333
|
+
}
|
334
|
+
|
335
|
+
|
336
|
+
static VALUE wiretap_audio_frames(VALUE self) {
|
337
|
+
Check_Node_Alive(self);
|
338
|
+
|
339
|
+
WireTapNodeHandle* node;
|
340
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
341
|
+
VALUE audioframes = Data_Wrap_Struct(cAudioFrames, 0, node_leave, node);
|
342
|
+
rb_iv_set(audioframes, "@node", self);
|
343
|
+
return audioframes;
|
344
|
+
}
|
345
|
+
|
346
|
+
|
347
|
+
|
348
|
+
|
349
|
+
void Init_node() {
|
350
|
+
|
351
|
+
cNode = rb_define_class_under(mWiretap, "Node", rb_cObject);
|
352
|
+
cClip = rb_define_class_under(mWiretap, "Clip", cNode);
|
353
|
+
cAudio = rb_define_class_under(mWiretap, "Audio", cNode);
|
354
|
+
cReel = rb_define_class_under(mWiretap, "Reel", cNode);
|
355
|
+
cLibrary = rb_define_class_under(mWiretap, "Library", cNode);
|
356
|
+
cProject = rb_define_class_under(mWiretap, "Project", cNode);
|
357
|
+
cVolume = rb_define_class_under(mWiretap, "Volume", cNode);
|
358
|
+
cHost = rb_define_class_under(mWiretap, "Host", cNode);
|
359
|
+
|
360
|
+
rb_define_alloc_func(cNode, wiretap_node_allocate);
|
361
|
+
rb_define_method(cNode, "id", VALUEFUNC(wiretap_node_get_id), 0);
|
362
|
+
rb_define_method(cNode, "id=", VALUEFUNC(wiretap_node_set_id), 1);
|
363
|
+
rb_define_method(cNode, "reload", VALUEFUNC(wiretap_node_reload), 0);
|
364
|
+
|
365
|
+
rb_define_method(cNode, "metadata", VALUEFUNC(wiretap_node_metadata), 0);
|
366
|
+
|
367
|
+
rb_define_method(cClip, "format", VALUEFUNC(wiretap_clip_format), 0);
|
368
|
+
rb_define_method(cAudio, "format", VALUEFUNC(wiretap_audio_format), 0);
|
369
|
+
rb_define_method(cClip, "frames", VALUEFUNC(wiretap_clip_frames), 0);
|
370
|
+
rb_define_method(cAudio, "frames", VALUEFUNC(wiretap_audio_frames), 0);
|
371
|
+
|
372
|
+
|
373
|
+
|
374
|
+
rb_define_method(cNode, "host?", VALUEFUNC(wiretap_false), -1);
|
375
|
+
rb_define_method(cNode, "volume?", VALUEFUNC(wiretap_false), -1);
|
376
|
+
rb_define_method(cNode, "project?", VALUEFUNC(wiretap_false), -1);
|
377
|
+
rb_define_method(cNode, "library?", VALUEFUNC(wiretap_false), -1);
|
378
|
+
rb_define_method(cNode, "reel?", VALUEFUNC(wiretap_false), -1);
|
379
|
+
rb_define_method(cNode, "clip?", VALUEFUNC(wiretap_false), -1);
|
380
|
+
rb_define_method(cNode, "audio?", VALUEFUNC(wiretap_false), -1);
|
381
|
+
|
382
|
+
rb_define_method(cHost, "host?", VALUEFUNC(wiretap_true), -1);
|
383
|
+
rb_define_method(cVolume, "volume?", VALUEFUNC(wiretap_true), -1);
|
384
|
+
rb_define_method(cProject, "project?", VALUEFUNC(wiretap_true), -1);
|
385
|
+
rb_define_method(cLibrary, "library?", VALUEFUNC(wiretap_true), -1);
|
386
|
+
rb_define_method(cReel, "reel?", VALUEFUNC(wiretap_true), -1);
|
387
|
+
rb_define_method(cClip, "clip?", VALUEFUNC(wiretap_true), -1);
|
388
|
+
rb_define_method(cAudio, "clip?", VALUEFUNC(wiretap_true), -1);
|
389
|
+
rb_define_method(cAudio, "audio?", VALUEFUNC(wiretap_true), -1);
|
390
|
+
|
391
|
+
|
392
|
+
rb_define_method(cNode, "find_child", VALUEFUNC(wiretap_node_find), 1);
|
393
|
+
rb_define_method(cNode, "type", VALUEFUNC(wiretap_node_get_type), 0);
|
394
|
+
rb_define_method(cNode, "name", VALUEFUNC(wiretap_node_get_name), 0);
|
395
|
+
|
396
|
+
rb_define_method(cClip, "import_directory", VALUEFUNC(wiretap_clip_import_directory), 1);
|
397
|
+
rb_define_protected_method(cNode, "create_node", VALUEFUNC(wiretap_node_create_node), -1);
|
398
|
+
rb_define_protected_method(cNode, "create_clip", VALUEFUNC(wiretap_node_create_clip), -1);
|
399
|
+
|
400
|
+
rb_define_method(cNode, "destroy!", VALUEFUNC(wiretap_node_destroy), 0);
|
401
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#include "wiretap.h"
|
2
|
+
|
3
|
+
|
4
|
+
static void wiretap_node_children_free(WireTapNodeHandle* node) {
|
5
|
+
}
|
6
|
+
|
7
|
+
|
8
|
+
static VALUE wiretap_node_children_count(VALUE self) {
|
9
|
+
WireTapNodeHandle* node;
|
10
|
+
int num;
|
11
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
12
|
+
RUN(node->getNumChildren(num));
|
13
|
+
return INT2FIX(num);
|
14
|
+
}
|
15
|
+
|
16
|
+
static VALUE wiretap_node_children_get_at(VALUE self, VALUE index) {
|
17
|
+
WireTapNodeHandle* node;
|
18
|
+
Check_Type(index, T_FIXNUM);
|
19
|
+
|
20
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
21
|
+
|
22
|
+
WireTapNodeHandle child;
|
23
|
+
RUN(node->getChild(FIX2INT(index), child));
|
24
|
+
|
25
|
+
return wiretap_node_create_with(child, rb_iv_get(self, "@server"), rb_iv_get(self, "@node"));
|
26
|
+
}
|
27
|
+
|
28
|
+
static VALUE wiretap_node_children_each(VALUE self) {
|
29
|
+
WireTapNodeHandle* node;
|
30
|
+
int i, num;
|
31
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
32
|
+
RUN(node->getNumChildren(num));
|
33
|
+
VALUE server = rb_iv_get(self, "@server");
|
34
|
+
VALUE parent = rb_iv_get(self, "@node");
|
35
|
+
|
36
|
+
for(i = 0; i < num; i++) {
|
37
|
+
WireTapNodeHandle child;
|
38
|
+
RUN(node->getChild(i, child));
|
39
|
+
rb_yield(wiretap_node_create_with(child, server, parent));
|
40
|
+
}
|
41
|
+
return self;
|
42
|
+
}
|
43
|
+
|
44
|
+
|
45
|
+
static VALUE wiretap_node_children(VALUE self) {
|
46
|
+
Check_Node_Alive(self);
|
47
|
+
|
48
|
+
WireTapNodeHandle* node;
|
49
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
50
|
+
VALUE children = Data_Wrap_Struct(cNodeChildren, 0, wiretap_node_children_free, node);
|
51
|
+
rb_iv_set(children, "@node", self);
|
52
|
+
rb_iv_set(children, "@server", rb_iv_get(self, "@server"));
|
53
|
+
return children;
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
void Init_children() {
|
58
|
+
|
59
|
+
rb_define_method(cNode, "children", VALUEFUNC(wiretap_node_children), 0);
|
60
|
+
cNodeChildren = rb_define_class_under(mWiretap, "NodeChildren", rb_cObject);
|
61
|
+
rb_define_method(cNodeChildren, "count", VALUEFUNC(wiretap_node_children_count), 0);
|
62
|
+
rb_define_method(cNodeChildren, "[]", VALUEFUNC(wiretap_node_children_get_at), 1);
|
63
|
+
rb_define_method(cNodeChildren, "each", VALUEFUNC(wiretap_node_children_each), 0);
|
64
|
+
|
65
|
+
}
|
66
|
+
|
67
|
+
|
data/ext/nodeframes.cpp
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
#include "wiretap.h"
|
2
|
+
|
3
|
+
#define NODERUN_E_FRAME(node, x) {if(!x) { \
|
4
|
+
frame.release(); \
|
5
|
+
rb_raise(eError, "Problem in wiretap: %s. File: %s: %d", node->lastError(), __FILE__, __LINE__); \
|
6
|
+
}}
|
7
|
+
|
8
|
+
/*
|
9
|
+
* Get frames count of clip
|
10
|
+
*/
|
11
|
+
static VALUE wiretap_node_frames_count(VALUE self) {
|
12
|
+
WireTapNodeHandle* node;
|
13
|
+
int num;
|
14
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
15
|
+
NODERUN_E(node, node->getNumFrames(num));
|
16
|
+
return INT2FIX(num);
|
17
|
+
}
|
18
|
+
|
19
|
+
/*
|
20
|
+
* Set frames count in clip
|
21
|
+
*/
|
22
|
+
static VALUE wiretap_node_frames_set_count(VALUE self, VALUE value) {
|
23
|
+
VALUE count = rb_funcall(value, rb_intern("to_i"), 0);
|
24
|
+
|
25
|
+
WireTapNodeHandle* node;
|
26
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
27
|
+
NODERUN_E(node, node->setNumFrames(NUM2INT(count)));
|
28
|
+
return count;
|
29
|
+
}
|
30
|
+
|
31
|
+
/*
|
32
|
+
* Get frame by index.
|
33
|
+
*/
|
34
|
+
static VALUE wiretap_node_frames_get_at(VALUE self, VALUE index) {
|
35
|
+
WireTapNodeHandle* node;
|
36
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
37
|
+
|
38
|
+
Check_Type(index, T_FIXNUM);
|
39
|
+
WireTapClipFormat format;
|
40
|
+
RUN(node->getClipFormat(format));
|
41
|
+
|
42
|
+
VALUE frame = rb_str_buf_new(format.frameBufferSize());
|
43
|
+
RSTRING(frame)->len = format.frameBufferSize();
|
44
|
+
|
45
|
+
NODERUN_E(node, node->readFrame(FIX2INT(index), STR(frame), LEN(frame)));
|
46
|
+
|
47
|
+
return frame;
|
48
|
+
}
|
49
|
+
|
50
|
+
/*
|
51
|
+
* Set frame at index. Accepts the formatted Stone image buffer as value.
|
52
|
+
*/
|
53
|
+
static VALUE wiretap_node_frames_set_at(VALUE self, VALUE index, VALUE value) {
|
54
|
+
WireTapNodeHandle* node;
|
55
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
56
|
+
Check_Type(index, T_STRING);
|
57
|
+
Check_Type(value, T_STRING);
|
58
|
+
|
59
|
+
NODERUN_E(node, node->writeFrame(FIX2INT(index), CSTR(value), LEN(value)));
|
60
|
+
return self;
|
61
|
+
}
|
62
|
+
|
63
|
+
/*
|
64
|
+
* Eval block on each frame
|
65
|
+
*/
|
66
|
+
static VALUE wiretap_node_frames_each(VALUE self) {
|
67
|
+
WireTapNodeHandle* node;
|
68
|
+
int i, num;
|
69
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
70
|
+
RUN(node->getNumFrames(num));
|
71
|
+
|
72
|
+
WireTapClipFormat format;
|
73
|
+
RUN(node->getClipFormat(format));
|
74
|
+
|
75
|
+
for(i = 0; i < num; i++) {
|
76
|
+
VALUE frame = rb_str_buf_new(format.frameBufferSize());
|
77
|
+
RSTRING(frame)->len = format.frameBufferSize();
|
78
|
+
|
79
|
+
RUN(node->readFrame(i, STR(frame), LEN(frame)));
|
80
|
+
//rb_iv_set(frame, "@path", wiretap_node_frames_get_path_at(self, INT2FIX(i)));
|
81
|
+
rb_yield(frame);
|
82
|
+
}
|
83
|
+
return self;
|
84
|
+
}
|
85
|
+
|
86
|
+
/*
|
87
|
+
* Get path of frame at index
|
88
|
+
*/
|
89
|
+
static VALUE wiretap_node_frames_get_path_at(VALUE self, VALUE index) {
|
90
|
+
WireTapNodeHandle* node;
|
91
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
92
|
+
|
93
|
+
Check_Type(index, T_FIXNUM);
|
94
|
+
|
95
|
+
WireTapStr path;
|
96
|
+
RUN(node->getFrameIdPath(FIX2INT(index), path));
|
97
|
+
|
98
|
+
return wiretap_to_str(path);
|
99
|
+
}
|
100
|
+
|
101
|
+
|
102
|
+
static void frame_prepare(VALUE self, WireTapNodeHandle** node, unsigned long* size, WireTapClipFormat** format) {
|
103
|
+
VALUE r_node = rb_iv_get(self, "@node");
|
104
|
+
VALUE r_format = rb_funcall(r_node, rb_intern("format"), 0);
|
105
|
+
|
106
|
+
WireTapNodeHandle* real_node;
|
107
|
+
Data_Get_Struct(self, WireTapNodeHandle, real_node);
|
108
|
+
*node = real_node;
|
109
|
+
|
110
|
+
WireTapClipFormat* real_format;
|
111
|
+
Data_Get_Struct(r_format, WireTapClipFormat, real_format);
|
112
|
+
*format = real_format;
|
113
|
+
|
114
|
+
*size = real_format->frameBufferSize();
|
115
|
+
}
|
116
|
+
|
117
|
+
/*
|
118
|
+
* Dump all frames into files, matched by pattern.
|
119
|
+
* @clip.frames.dump_all("/tmp/clip/%d.sgi")
|
120
|
+
*
|
121
|
+
* It is substituted via snprintf
|
122
|
+
*/
|
123
|
+
static VALUE wiretap_node_frame_dump_all(VALUE self, VALUE file_pattern) {
|
124
|
+
WireTapNodeHandle* node;
|
125
|
+
unsigned long size;
|
126
|
+
WireTapClipFormat* format;
|
127
|
+
frame_prepare(self, &node, &size, &format);
|
128
|
+
|
129
|
+
int frame_count = NUM2INT(rb_funcall(self, rb_intern("count"), 0));
|
130
|
+
std::auto_ptr<unsigned char> frame(new unsigned char[size]);
|
131
|
+
for(int i = 0; i < frame_count; i++) {
|
132
|
+
NODERUN_E_FRAME(node, node->readFrame(i, frame.get(), size));
|
133
|
+
size_t buffer_size = PATH_MAX;
|
134
|
+
char file_name[buffer_size];
|
135
|
+
snprintf(file_name, buffer_size, STR(file_pattern), i);
|
136
|
+
wiretap_write_image_frame(format->width(), format->height(), format->bitsPerPixel(), frame.get(), file_name);
|
137
|
+
}
|
138
|
+
|
139
|
+
return self;
|
140
|
+
}
|
141
|
+
|
142
|
+
/*
|
143
|
+
* Dump one frame to file
|
144
|
+
*/
|
145
|
+
static VALUE wiretap_node_frame_dump(VALUE self, VALUE index, VALUE file) {
|
146
|
+
WireTapNodeHandle* node;
|
147
|
+
unsigned long size;
|
148
|
+
WireTapClipFormat* format;
|
149
|
+
frame_prepare(self, &node, &size, &format);
|
150
|
+
|
151
|
+
std::auto_ptr<unsigned char> frame(new unsigned char[size]);
|
152
|
+
NODERUN_E_FRAME(node, node->readFrame(NUM2INT(index), frame.get(), size));
|
153
|
+
|
154
|
+
wiretap_write_image_frame(format->width(), format->height(), format->bitsPerPixel(), frame.get(), CSTR(file));
|
155
|
+
return self;
|
156
|
+
}
|
157
|
+
|
158
|
+
/*
|
159
|
+
* Read one frame from a PPM file. If this is the first frame (index 0) and the clip has no frames yet one frame will be allocated.
|
160
|
+
* You cannot change the number of frames afterwards.
|
161
|
+
* THIS METHOD SHOULD BE PRIVATE DAMN!
|
162
|
+
*/
|
163
|
+
static VALUE wiretap_node_frame_write_from_file(VALUE self, VALUE index, VALUE filename) {
|
164
|
+
WireTapNodeHandle* node;
|
165
|
+
WireTapClipFormat format;
|
166
|
+
|
167
|
+
Data_Get_Struct(self, WireTapNodeHandle, node);
|
168
|
+
NODERUN_E(node, node->getClipFormat(format));
|
169
|
+
|
170
|
+
unsigned int bufSize = format.frameBufferSize();
|
171
|
+
std::auto_ptr<unsigned char> frame(new unsigned char[bufSize]);
|
172
|
+
|
173
|
+
int i = NUM2INT(index);
|
174
|
+
|
175
|
+
FILE* infile = fopen(CSTR(filename), "r");
|
176
|
+
if(!infile) {
|
177
|
+
frame.release();
|
178
|
+
THROW("Couldn't open file %s for reading", filename);
|
179
|
+
}
|
180
|
+
|
181
|
+
if(!ppm_read_format(infile, &format)) {
|
182
|
+
frame.release();
|
183
|
+
fclose(infile);
|
184
|
+
THROW("Couldn't read PPM format from file %s", filename);
|
185
|
+
}
|
186
|
+
|
187
|
+
if(!ppm_read_image(infile, frame.get(), format.width(), format.height(), format.bitsPerPixel())) {
|
188
|
+
frame.release();
|
189
|
+
fclose(infile);
|
190
|
+
THROW("Couldn't read PPM image data from file %s", filename);
|
191
|
+
}
|
192
|
+
|
193
|
+
fclose(infile);
|
194
|
+
|
195
|
+
int totalFrms;
|
196
|
+
NODERUN_E_FRAME(node, node->getNumFrames(totalFrms));
|
197
|
+
|
198
|
+
/* Edge case - If we are setting the first frame and the clip has no frames */
|
199
|
+
if ((totalFrms == i) && (i == 0)) {
|
200
|
+
NODERUN_E_FRAME(node, node->setNumFrames(i+1)); /* wiretapd will crash on setNumFrames(0) */
|
201
|
+
} else if (i >= totalFrms) {
|
202
|
+
/* Edge case - trying to add a frame to a clip after the fact will crash wiretapd */
|
203
|
+
frame.release();
|
204
|
+
THROW("You cannot add frames to an existing clip");
|
205
|
+
}
|
206
|
+
|
207
|
+
NODERUN_E_FRAME(node, node->writeFrame(i, frame.get(), bufSize));
|
208
|
+
return self;
|
209
|
+
}
|
210
|
+
|
211
|
+
|
212
|
+
void Init_nodeframes() {
|
213
|
+
|
214
|
+
cNodeFrames = rb_define_class_under(mWiretap, "NodeFrames", rb_cObject);
|
215
|
+
|
216
|
+
rb_define_method(cNodeFrames, "count", VALUEFUNC(wiretap_node_frames_count), 0);
|
217
|
+
rb_define_method(cNodeFrames, "count=", VALUEFUNC(wiretap_node_frames_set_count), 1);
|
218
|
+
rb_define_method(cNodeFrames, "[]", VALUEFUNC(wiretap_node_frames_get_at), 1);
|
219
|
+
rb_define_method(cNodeFrames, "[]=", VALUEFUNC(wiretap_node_frames_set_at), 2);
|
220
|
+
rb_define_method(cNodeFrames, "path_at", VALUEFUNC(wiretap_node_frames_get_path_at), 1);
|
221
|
+
rb_define_method(cNodeFrames, "each", VALUEFUNC(wiretap_node_frames_each), 0);
|
222
|
+
|
223
|
+
rb_define_method(cNodeFrames, "dump", VALUEFUNC(wiretap_node_frame_dump), 2);
|
224
|
+
rb_define_method(cNodeFrames, "dump_all", VALUEFUNC(wiretap_node_frame_dump_all), 1);
|
225
|
+
|
226
|
+
rb_define_method(cNodeFrames, "write_from_file", VALUEFUNC(wiretap_node_frame_write_from_file), 2);
|
227
|
+
|
228
|
+
cAudioFrames = rb_define_class_under(mWiretap, "AudioFrames", cNodeFrames);
|
229
|
+
rb_define_method(cAudioFrames, "dump", VALUEFUNC(wiretap_false), -1);
|
230
|
+
rb_define_method(cAudioFrames, "read", VALUEFUNC(wiretap_false), -1);
|
231
|
+
rb_define_method(cAudioFrames, "dump_all", VALUEFUNC(wiretap_false), -1);
|
232
|
+
|
233
|
+
}
|