Dear Pd list,
the [pix_data] object has me very confused! I am using it for analysis of a live webcam video or recorded video clip from [pix_video] or [pix_film]. However, I cannot for the life of me figure out where it is getting the analysis data from!
I can disconnect the Gemlist from the second inlet, so that it is only getting the metro bangs at the first inlet and the X and Y coordinates to analyze at the third and fourth inlet, and still it gives data output.
I know that it is still getting the changing video signal and not just reading the last frame that came in the Gemlist, because I use the analysis data to reconstruct the image with audio signals on an external analog vector monitor, and I see that image changing and moving even if the [pix_data] receives no Gemlist.
Basically, if I use [pix_video] or [pix_film], I can completely disconnect their outlets from anything, and as long as they were connected to [pix_data] through an active Gemlist before I disconnect them, then [pix_data] will still continue to see them in realtime.
Also, no scaling transformations I do to the output of [pix_video] or [pix_film] (for example by texturing it on a rectangle with a [scale] object in front of it) have any effect on what is seen by [pix_data].
Does [pix_data] read the pixel values from some other place than the Gemlist? A buffer of some kind? How can I apply any transformations to what it "sees"?
Thank you for clearing up any confusion here! Derek
derek holzer noise.art.technology http://macumbista.net
On 02/27/2018 11:50 PM, Derek Holzer wrote:
I can disconnect the Gemlist from the second inlet, so that it is only getting the metro bangs at the first inlet and the X and Y coordinates to analyze at the third and fourth inlet, and still it gives data output.
I know that it is still getting the changing video signal and not just reading the last frame that came in the Gemlist, because I use the analysis data to reconstruct the image with audio signals on an external analog vector monitor, and I see that image changing and moving even if the [pix_data] receives no Gemlist.
what you are seeing is an artifact of the implementation. pixel data is handed between objects by means of a pointer into memory (which is one of the things stored in the ominous "GemList")
[pix_data] remembers that pointer so it can access the data whenever you "bang" it. if you disconnect the 2nd inlet of a [pix_data] object, it will still remember the last image you sent it - and you can still access it.
now the reason why the data is changing, is because Gem does most of it's stuff in-place, that is: it doesn't copy each of your 4k video frames for every object it goes through. instead all the objects *share* the pixel data (which is the reason why you can see "spill over" of pix-fx from one branch of your graph to another). in your case this means, that the memory where [pix_data] is reading from is the same as the memory where [pix_video] is writing to. thus [pix_data] sees updated pixels.
it is somewhat similar to arrays, where a [tabread] sees updated data even if you disconnect the "set" message. (but probably much less safe - you *might* trigger memory corruption by disconnecting [pix_data] and then somehow invalidating the memory it reads from - which could be as simple as changing the reslution of [pix_video])
Also, no scaling transformations I do to the output of [pix_video] or [pix_film] (for example by texturing it on a rectangle with a [scale] object in front of it) have any effect on what is seen by [pix_data].
hopefully. the pix_* space and the openGL space are two entirely different things. pixel data resides in the main memory of your computer. [pix_data] gives you access to this main memory. [pix_texture] copies the data to your gfx card. [scale] and [rotate] and practically all Gem objects (not prefixed with pix_) operate directly on te gfx card. whatever is done to the image data on the gfx card, has no effect on the contents in main memory.
Does [pix_data] read the pixel values from some other place than the Gemlist? A buffer of some kind? How can I apply any transformations to what it "sees"?
the naive way to do that would be using [pix_snapshot] which is the inverse of [pix_texture] (it copies image data from the gfx card to the main memory). (i call it "naive" as it is an execution path not optimized by modern gfx cards, so it might be slower than expected.) the non-naive solution would be to not require the a transfer from gfx-card to main memory and do everything on the gfx card (see also: shaders). depending on the task you want to solve, this might be feasible or not (in which case go back to [pix_snapshot])
gfmdasr IOhannes
just a little remark : This is [pix_snap] (and not [pix_snapshot]) to get back pixels buffer from your gfx card to the RAM of your computer ;) ++
Jack
Le 28/02/2018 à 09:54, IOhannes m zmölnig a écrit :
On 02/27/2018 11:50 PM, Derek Holzer wrote:
I can disconnect the Gemlist from the second inlet, so that it is only getting the metro bangs at the first inlet and the X and Y coordinates to analyze at the third and fourth inlet, and still it gives data output.
I know that it is still getting the changing video signal and not just reading the last frame that came in the Gemlist, because I use the analysis data to reconstruct the image with audio signals on an external analog vector monitor, and I see that image changing and moving even if the [pix_data] receives no Gemlist.
what you are seeing is an artifact of the implementation. pixel data is handed between objects by means of a pointer into memory (which is one of the things stored in the ominous "GemList")
[pix_data] remembers that pointer so it can access the data whenever you "bang" it. if you disconnect the 2nd inlet of a [pix_data] object, it will still remember the last image you sent it - and you can still access it.
now the reason why the data is changing, is because Gem does most of it's stuff in-place, that is: it doesn't copy each of your 4k video frames for every object it goes through. instead all the objects *share* the pixel data (which is the reason why you can see "spill over" of pix-fx from one branch of your graph to another). in your case this means, that the memory where [pix_data] is reading from is the same as the memory where [pix_video] is writing to. thus [pix_data] sees updated pixels.
it is somewhat similar to arrays, where a [tabread] sees updated data even if you disconnect the "set" message. (but probably much less safe - you *might* trigger memory corruption by disconnecting [pix_data] and then somehow invalidating the memory it reads from - which could be as simple as changing the reslution of [pix_video])
Also, no scaling transformations I do to the output of [pix_video] or [pix_film] (for example by texturing it on a rectangle with a [scale] object in front of it) have any effect on what is seen by [pix_data].
hopefully. the pix_* space and the openGL space are two entirely different things. pixel data resides in the main memory of your computer. [pix_data] gives you access to this main memory. [pix_texture] copies the data to your gfx card. [scale] and [rotate] and practically all Gem objects (not prefixed with pix_) operate directly on te gfx card. whatever is done to the image data on the gfx card, has no effect on the contents in main memory.
Does [pix_data] read the pixel values from some other place than the Gemlist? A buffer of some kind? How can I apply any transformations to what it "sees"?
the naive way to do that would be using [pix_snapshot] which is the inverse of [pix_texture] (it copies image data from the gfx card to the main memory). (i call it "naive" as it is an execution path not optimized by modern gfx cards, so it might be slower than expected.) the non-naive solution would be to not require the a transfer from gfx-card to main memory and do everything on the gfx card (see also: shaders). depending on the task you want to solve, this might be feasible or not (in which case go back to [pix_snapshot])
gfmdasr IOhannes
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
Would saving (cmd+s) make pix_data forget a pointer, as in [text] or [array] objects when using pointers? (also, perhaps the [pointer] object itself, but I havent tested this)
On Feb 28, 2018, at 9:54 AM, IOhannes m zmölnig zmoelnig@iem.at wrote:
[pix_data] remembers that pointer
On 02/28/2018 10:53 AM, Fede Camara Halac wrote:
Would saving (cmd+s) make pix_data forget a pointer, as in [text] or [array] objects when using pointers?
that sounds very fishy to. do you have a patch that exposes the forget-on-save behaviour of [array] or [text]?
gfmdasr IOhannes
Ok, so it is a combination of editing the canvas and pointer memory
i don’t think it has to do with saving. also, i don’t think it would relate to the previous pix_data pointer issue
Here’s a patch
On Feb 28, 2018, at 11:24 AM, IOhannes m zmölnig zmoelnig@iem.at wrote:
On 02/28/2018 10:53 AM, Fede Camara Halac wrote:
Would saving (cmd+s) make pix_data forget a pointer, as in [text] or [array] objects when using pointers?
that sounds very fishy to. do you have a patch that exposes the forget-on-save behaviour of [array] or [text]?
gfmdasr IOhannes
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
I noticed this issue ca. one year ago when I started working on a complex project with data structures which involved dynamically adding/deleting objects to/from a canvas. I even submitted a bug report: https://sourceforge.net/p/pure-data/bugs/1282/
since I've recently started doing a couple a PRs, this is something I want to investigate too.
to explain the problem quickly:
a glist (list of graphical objects) is internally implemented as a linked list. usually, a big advantage of a linked lists is that adding/deleting elements won't touch other elements (especially doesn't move them in memory, like it can happen with dynamically sized arrays). I don't see why adding/deleting graphical objects should invalidate any gpointers - apart from those which pointed to the deleted element(s).
I guess it's meant as a means to keep Pd pointers safe - but what situation does it try it prevent? and why are gpointers also invalidated if you add/delete "normal" text objects which are not scalars (and so no gpointer could possibly point to it)?
any pointers (no pun intended) to the reasons behind this desigin decision are highly appreciated :-)
Gesendet: Mittwoch, 28. Februar 2018 um 12:17 Uhr Von: Fede camarafede@gmail.com An: pd-list@lists.iem.at Betreff: [PD] stale pointers after object creation (was Re: pix_data issue)
Ok, so it is a combination of editing the canvas and pointer memory
i don’t think it has to do with saving. also, i don’t think it would relate to the previous pix_data pointer issue
Here’s a patch
On Feb 28, 2018, at 11:24 AM, IOhannes m zmölnig zmoelnig@iem.at wrote:
On 02/28/2018 10:53 AM, Fede Camara Halac wrote:
Would saving (cmd+s) make pix_data forget a pointer, as in [text] or [array] objects when using pointers?
that sounds very fishy to. do you have a patch that exposes the forget-on-save behaviour of [array] or [text]?
gfmdasr IOhannes
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
a glist (list of graphical objects) is internally implemented as a linked list. usually, a big
advantage of a linked lists is that adding/deleting elements won't touch other elements
(especially doesn't move them in memory, like it can happen with dynamically sized arrays).
That's the theory.
In practice the insidious audio dropouts happen when Pd is
*iterating* over a glist, not when adding/deleting objects.
This is because users learn relatively quickly the simple rule
that adding/deleting objects rebuilds the signal graph, so they
avoid doing that if at all possible during performance.
However, users generally have no idea what triggers a walk through
the glist linked list. And those trips can easily cause dropouts
during a performance-- even merely moving the mouse over a canvas.
So in practice, glist as linked list optimizes for the case not
often used in realtime performance and is a detriment to performance
in the cases where it matters (esp. compared to iterating over an
array, though the number of glist iterations with things like
mouse motion might trip up audio anyway).
-Jonathan
OK, I see that the refcount is not per scalar but per glist (in t_gstub) so if I understand correctly it's not possible to selectively invalidate gpointers only for the deleted scalars.
also I have to correct myself: adding scalars doesn't invalidate pointers.
so the remaining problem is adding/deleting non-scalar objects. do you consider this a bug or is this by design? if it's a bug I'll make a PR to fix it. I attached a simple test case to illustrate the problem.
Christof
Gesendet: Mittwoch, 28. Februar 2018 um 13:54 Uhr Von: "Christof Ressi" christof.ressi@gmx.at An: pd-list pd-list@iem.at Cc: "Miller Puckette" msp@ucsd.edu Betreff: Re: [PD] stale pointers after object creation (was Re: pix_data issue)
I noticed this issue ca. one year ago when I started working on a complex project with data structures which involved dynamically adding/deleting objects to/from a canvas. I even submitted a bug report: https://sourceforge.net/p/pure-data/bugs/1282/
since I've recently started doing a couple a PRs, this is something I want to investigate too.
to explain the problem quickly:
a glist (list of graphical objects) is internally implemented as a linked list. usually, a big advantage of a linked lists is that adding/deleting elements won't touch other elements (especially doesn't move them in memory, like it can happen with dynamically sized arrays). I don't see why adding/deleting graphical objects should invalidate any gpointers - apart from those which pointed to the deleted element(s).
I guess it's meant as a means to keep Pd pointers safe - but what situation does it try it prevent? and why are gpointers also invalidated if you add/delete "normal" text objects which are not scalars (and so no gpointer could possibly point to it)?
any pointers (no pun intended) to the reasons behind this desigin decision are highly appreciated :-)
Gesendet: Mittwoch, 28. Februar 2018 um 12:17 Uhr Von: Fede camarafede@gmail.com An: pd-list@lists.iem.at Betreff: [PD] stale pointers after object creation (was Re: pix_data issue)
Ok, so it is a combination of editing the canvas and pointer memory
i don’t think it has to do with saving. also, i don’t think it would relate to the previous pix_data pointer issue
Here’s a patch
On Feb 28, 2018, at 11:24 AM, IOhannes m zmölnig zmoelnig@iem.at wrote:
On 02/28/2018 10:53 AM, Fede Camara Halac wrote:
Would saving (cmd+s) make pix_data forget a pointer, as in [text] or [array] objects when using pointers?
that sounds very fishy to. do you have a patch that exposes the forget-on-save behaviour of [array] or [text]?
gfmdasr IOhannes
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list