GNOME Bugzilla – Bug 706531
Segfault when trying to get data.
Last modified: 2014-06-17 20:34:14 UTC
So I have everything installed. I have built with the Gobject introspection flags. The viewer appears to be working fine as well. I can run the python test under the test directory, it seems to be getting buffers fine. I run 'arv-camera-test' and it appears to connect to the camera, get information and retrieve the 10 buffers. Now I actually want to get the image data from the buffers, this is where it seems to segfault. If I pop a buffer and try to get: buffer.data Is where it will segfault. We have also tried to create a string buffer and use the buffer.get_data(myDefinedBufferString) but that doesn't seem to do anything. Maybe I'm confused on how I would retrieve the image data. Is there something else I need to do? Camera Information: Camera vendor : Basler Camera model : acA1300-30gc Camera id : 21343333 ROI : 128x128 at 0,0 Payload : 16384 Pixel format : Mono8 Please let me know if there is anything I can test or do to try and get this working. I feel like I'm so close and just want to get it working so SimpleCV can have Aravis support and offer a broader range of camera support.
Hi. Can you confirm you are using git master ? Could you attach a sample code that triggers the segfault ? Thanks.
I am using git master checked out on commit id (90f9b30546a9e1e567261f245e29928cdc40c39f). We have solved it, the way we had to do it (probably not the correct way), was to not use pointers but just return the data on the C code. The python code I was using to get it to segfault was: import sys import time from gi.repository import Aravis camera = Aravis.Camera.new (None) camera.set_region (0,0,128,128) camera.set_frame_rate (10.0) camera.set_pixel_format (Aravis.PIXEL_FORMAT_MONO_8) payload = camera.get_payload () [x,y,width,height] = camera.get_region () stream = camera.create_stream (None, None) for i in range(0,10): stream.push_buffer (Aravis.Buffer.new_allocate (payload)) camera.start_acquisition () for i in range(0,20): buffer = stream.pop_buffer () print buffer.data # HERE IS WHERE IT SEGFAULTS To fix it we modified arvbuffer.c and added the function: guint64 arv_buffer_data_address (ArvBuffer *buffer) { return (guint64) buffer->data; } This seems to work fine when adding and recompiling. I'm not sure if there is another best practice or this is fine. If so I can submit a pull request if you'd like.
I've checked with git master and can not reproduce your issue: Camera vendor : Smartek Camera model : GC651M Camera id : 0050c27084be ROI : 128x128 at 0,0 Payload : 16384 Pixel format : Mono8 Start acquisition Acquisition 39019520 39035920 39525968 39542368 39558768 39575168 39591568 39607968 39624368 39640768 39019520 39035920 39525968 39542368 39558768 39575168 39591568 39607968 39624368 39640768 Stop acquisition with: for i in range(0,20): buffer = stream.pop_buffer () print buffer.data if buffer: stream.push_buffer (buffer) Do you still see the bug using git master ?
Yep, have the latest on master (commit id: 1d9292045a1584b647df1a579eaf8309ba0a0bb2) Still getting the segfault regardless of what camera I use. I tested with Basler Ace (aca1300) and a Allied Vision Prosilica GT 2300. It gets the segfault at the print buffer.data.
Could you attach the result of: ARV_DEBUG=all:3 ./launch arv-camera-test.py > output.txt (as a zipped file please). Which distribution are you using ? Which platform ? Thanks.
I've pushed a patch to master that should fix your issue. Could you test it please ? https://git.gnome.org/browse/aravis/commit/?id=1385d2a4687f5da623181143bd9308d693819d4b
Created attachment 278208 [details] [review] Patch to fix pointer type
Your patch did not fix the bug for me (master on 64-bit Linux Mint 17). Python interprets the char pointer as a string, so it is cut off when there is a black pixel (null byte). Changing the data to a `gpointer *` type fixes it for me. I can then read the image data using im = numpy.fromstring(ctypes.string_at(buf.data, buf.size), dtype = numpy.uint8).reshape(buf.height, buf.width) where buf is the buffer. See the above patch.
> Changing the data to a `gpointer *`. That does not sound right. A gpointer is already a pointer (actually it's void *). So changing the type of buffer->data to gpointer * is not he right thing to do. Did you try guint8 *, or uint8_t * ?
Review of attachment 278208 [details] [review]: Did you try guint8 *, or uint8_t * ?
The first thing I tried was guint8 *. The problem is it gets interpreted as a single integer instead of an array. I've tried to add GObject-Introspection annotations so it gets treated as an array with length size, which would be ideal, but I can't get it to get interpreted correctly. As a gpointer * (or a void *), Python gets the address of the array, which can then be used to read in the data using NumPy.
I guess the correct solution is to use a data accessor function. Matthew, could you try the following patch to retrieve the buffer data using the get_data accessor.
Created attachment 278321 [details] [review] Data accessor patch
The patch works well. The accessor function returns a string containing the full image data, instead of terminating at the first zero byte. Thanks.
Patch pushed to git master. Thanks Matthew.