Hallo gem devs!
I need some fast changing images and so I added a open-message to pix_buffer_write, so that I can load an image into the buffer. I read the image like this:
imageStruct *image = NULL; canvas_makefilename(getCanvas(), filename->s_name, buf, MAXPDSTRING); image = image2mem(buf);
so my question is: do I need all the cache-stuff like in pix_image, or is a simple image2mem sufficient (like above) ?
Now for the next: pix_buffer_read I just noticed, that pix_buffer_read needs much more cpu than pix_image, because stuff like this:
Obj_header*ohead=(Obj_header*)pd_findbyclass(m_bindname, pix_buffer_class); [...] pix_buffer *buffer=(pix_buffer *)(ohead)->data; [..] img=buffer->getMess((int)m_frame); if (img && img->data) img->copy2ImageStruct(&state->image->image);
is called every frame! So I'm thinking about, how to handle it in a more efficient way - maybe the best solution would be to check for a buffer and image only when the index changes ?
Thanks, LG Georg
Georg Holzmann wrote:
Hallo gem devs!
thanks for the files:
I need some fast changing images and so I added a open-message to pix_buffer_write, so that I can load an image into the buffer. I read the image like this:
imageStruct *image = NULL; canvas_makefilename(getCanvas(), filename->s_name, buf, MAXPDSTRING); image = image2mem(buf);
so my question is: do I need all the cache-stuff like in pix_image, or is a simple image2mem sufficient (like above) ?
no you don't necessarily need the cache.
however, i reject your patch, since i don't think that [pix_buffer_write] is the apropriate place for this operation. instead of have moved the open()-functionality into [pix_buffer] itself.
(i consider the pix_buffer-objects very much like the table-objects within pd: you don't tell [tabwrite] to load a file into a table, rather you send the request directly to the table (or use a specialized object))
Now for the next: pix_buffer_read I just noticed, that pix_buffer_read needs much more cpu than pix_image, because stuff like this:
Obj_header*ohead=(Obj_header*)pd_findbyclass(m_bindname, pix_buffer_class); [...] pix_buffer *buffer=(pix_buffer *)(ohead)->data; [..] img=buffer->getMess((int)m_frame); if (img && img->data) img->copy2ImageStruct(&state->image->image);
is called every frame!
the problem with your solution is, that it crashes as soon, as you delete the associated [pix_buffer] object.
to fix this, you _have_ to do a pd_findbyclass() each and everytime you access the data behind it.
i have done so and you can find both your improvements in the CVS-head.
mfga.ds.r IOhannes
Hallo!
(i consider the pix_buffer-objects very much like the table-objects within pd: you don't tell [tabwrite] to load a file into a table, rather you send the request directly to the table (or use a specialized object))
okay, now I understand how you are thinking ;) should I implement it to pix_buffer or have you already done it?
the problem with your solution is, that it crashes as soon, as you delete the associated [pix_buffer] object.
to fix this, you _have_ to do a pd_findbyclass() each and everytime you access the data behind it.
no, you dont have to :) because the pixBlock is stored in the class - so I only must use pd_findbyclass() when the index changes of course ... (and I didn't do that) (file attached)
LG Georg
Georg Holzmann wrote:
Hallo!
(i consider the pix_buffer-objects very much like the table-objects within pd: you don't tell [tabwrite] to load a file into a table, rather you send the request directly to the table (or use a specialized object))
okay, now I understand how you are thinking ;) should I implement it to pix_buffer or have you already done it?
it is already in the CVS
the problem with your solution is, that it crashes as soon, as you delete the associated [pix_buffer] object.
to fix this, you _have_ to do a pd_findbyclass() each and everytime you access the data behind it.
no, you dont have to :)
no you have to
because the pixBlock is stored in the class - so I only must use pd_findbyclass() when the index changes of course ... (and I didn't do that) (file attached)
while you are copying the struct-data into your local pixBlock, the actual pixel-data is stored in the [pix_buffer] (using copy2imageStruct() instead of copy2Image()) and it is freed when pix_buffer is deleted.
just open the example patch in examples/2.advanced load the buffer, change the index and delete the [pix_buffer] object.
i always tried with "auto 1"
mfg.asd.r IOhannes
Hallo!
to fix this, you _have_ to do a pd_findbyclass() each and everytime you access the data behind it.
no, you dont have to :)
no you have to
but I don't want to ... :)
while you are copying the struct-data into your local pixBlock, the actual pixel-data is stored in the [pix_buffer] (using copy2imageStruct() instead of copy2Image()) and it is freed when pix_buffer is deleted.
okay, I can see it in GemPixUtils. Then I will use refreshImage(imageStruct *to) ...
just open the example patch in examples/2.advanced load the buffer, change the index and delete the [pix_buffer] object.
i always tried with "auto 1"
doesn't crash here ... but it's only luck it seems ...
LG Georg
Hallo!
i hope it is working now also with your debug patch, file attached ...
LG Georg
Georg Holzmann wrote:
Hallo!
i hope it is working now also with your debug patch, file attached ...
yes this works fine; but now you are using refreshImage() to copiy all the data (that is why it is not crashing) this should make the new version of [pix_buffer_read] considerably slower (esp. in "auto"-mode), since the old version only copied the meta-data. have you benchmarked this (i haven't)
speaking of auto: to allow reverse playback you really should test whether auto is ==0.0 (or approx. 0) instead of >=
mfg.asd.r IOhannes
Hallo!
okay, this seems to become a long thread ...
this should make the new version of [pix_buffer_read] considerably slower (esp. in "auto"-mode), since the old version only copied the meta-data. have you benchmarked this (i haven't)
no - did no benchmarking. but I changed it back now to copy2ImageStruct and managed it with the flag m_haveImage so that it won't crash here - please test it again with your patch ...
speaking of auto: to allow reverse playback you really should test whether auto is ==0.0 (or approx. 0) instead of >=
okay, i understand ... changed
I also attached a new helpfile for [pix_buffer], with the open message.
LG Georg
#N canvas 458 216 661 423 10; #X text 452 8 GEM object; #X obj 9 263 cnv 15 430 150 empty empty empty 20 12 0 14 -233017 -66577 0; #X text 40 265 Inlets:; #X obj 9 227 cnv 15 430 30 empty empty empty 20 12 0 14 -195568 -66577 0; #X text 18 226 Arguments:; #X obj 8 56 cnv 15 430 165 empty empty empty 20 12 0 14 -233017 -66577 0; #X obj 452 75 cnv 15 200 170 empty empty empty 20 12 0 14 -228992 -66577 0; #X text 461 54 Example:; #X obj 457 120 cnv 15 190 120 empty empty empty 20 12 0 14 -24198 -66577 0; #X text 71 31 Class: pix object; #X text 29 57 Description: a storage place for a number of images; #X text 11 79 [pix_buffer] is a named storage place for images. It is quite similar to pd's [table] object (but you cannot open it and have a look at it's contents).; #X text 50 11 Synopsis: [pix_buffer]; #X text 23 281 Inlet 1: bang: get the size of the buffer in frames ; #X text 23 333 Inlet 1: message: allocate <xsize> <ysize> <bytes_per_pixel>: assume that all images in the pix_buffer will have the given dimension and preallocate memory for them.; #X text 12 123 The images stored in the [pix_buffer] can have different dimensions and coulorspaces. Memory is reserved on demand , but you can preallocate memory with the [allocate( message.; #X text 23 391 Outlet 1: int: size of the buffer; #X msg 464 128 bang; #X floatatom 464 216 5 0 0 0 - - -; #X msg 510 164 allocate 256 256 4; #X text 462 266 see also:; #X obj 475 318 pix_buffer_read; #X obj 474 293 pix_buffer_write; #X text 64 237 list: <buffer_name> <size>; #X obj 464 193 pix_buffer depot 10; #X text 10 170 To write data to the [pix_buffer] or get images from it , you can use separate objects [pix_buffer_write] and [pix_buffer_read] or the [open( message.; #X text 23 300 Inlet 1: open: filename index: put an image into the pix_buffer at the given index; #X obj 510 80 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #N canvas 0 0 450 300 openpanel 0; #X obj 114 62 inlet; #X obj 121 254 outlet; #X obj 114 125 openpanel; #X msg 114 162 set open $1; #X obj 114 199 t b a; #X connect 0 0 2 0; #X connect 2 0 3 0; #X connect 3 0 4 0; #X connect 4 0 1 0; #X connect 4 1 1 0; #X restore 510 97 pd openpanel; #X msg 510 132 open somefile.jpg; #X connect 17 0 24 0; #X connect 19 0 24 0; #X connect 24 0 18 0; #X connect 27 0 28 0; #X connect 28 0 29 0; #X connect 29 0 24 0;
Hallo IOhannes!
just have seen your changes to pix_buffer_read, but you forgot to remove the methode update_pix_buffer() from the header (or I checked it out wrong) - so Gem can't load!
changes attached!
LG Georg