Issue parsing chunk data in Python

I am hopeful that someone more experienced can explain what I am doing wrong.
I have looked at the at Symbol Mappings and a few examples and cant really see where I am going wrong.

I am trying to capture a frame and its chunk data. Then (for now) just print out the Timestamp. The next step will be calling my blob tracker and sending the frame to it.

My issue is that when I try to parse the chunk data, a gc error 5 (No device set) gets thrown. I see in the Mapping there is an Aravis.Camera.create_chunk_parser() as well as an Aravis.Device.create_chunk_parser() but it is not clear to me the difference. They look to both produce an Aravis.ChunkParser

Here is my code

import sys
import gi
gi.require_version ('Aravis', '0.8')
from gi.repository import Aravis

try:
    camera = Aravis.Camera.new (None)
except TypeError:
	print ("No camera found")
	exit ()

camera.set_region (0,0,128,128)
camera.set_frame_rate (15.0)
camera.set_pixel_format (Aravis.PIXEL_FORMAT_MONO_8)

# Create chunk parser
chunk_parser = camera.create_chunk_parser()
  
# Enable chunk data: Width, Height, Timestamp  
if camera.are_chunks_available():
    camera.set_chunks("Width,Height,Timestamp")
else:
    print("Chunk data not available for this camera")

payload = camera.get_payload ()
[x,y,width,height] = camera.get_region ()

# Print camera info
print ("Camera vendor : %s" %(camera.get_vendor_name ()))
print ("Camera model  : %s" %(camera.get_model_name ()))
print ("ROI           : %dx%d at %d,%d" %(width, height, x, y))
print ("Payload       : %d" %(payload))
print ("Pixel format  : %s" %(camera.get_pixel_format_as_string ()))

stream = camera.create_stream (None, None)

# Create pool of buffers for capturing
for i in range(0,20):
	stream.push_buffer (Aravis.Buffer.new_allocate (payload))

print ("Starting...")
camera.start_acquisition ()

#Enter main loop to gather frame and chunk data and print data to screen
try:
    for i in range(0,20):
        image = stream.pop_buffer ()
        print (image)
        if image:
            if image.has_chunks:
                width = chunk_parser.get_integer_value(image, "Width")
                print("Width: ", width)
                ts = chunk_parser.get_float_value(image, "Timestamp")
                print("Timestamp: ", ts)
            stream.push_buffer (image)
except Exception as error:
    print(error)

finally:
    print ("Stopping.")
    camera.stop_acquisition ()

And the error indicating I have no device set:

root@imx8qm:/test/bin# python3 arv-chunk-test.py
Camera vendor : FLIR
Camera model  : Blackfly S BFS-U3-120S4C
ROI           : 128x128 at 0,0
Payload       : 16444
Pixel format  : Mono8
Starting...
<Aravis.Buffer object at 0xffff8ec69b80 (ArvBuffer at 0xaaaaf730fa20)>
arv-gc-error-quark: [Width] [Width_Val] [Device] No device set (5)
Stopping.

Follow up after coming across [arvchunkparsertest.c](http://github.com/AravisProject/aravis/blob/main/tests/arvchunkparsertest.c) ,and realizing I had a typo missing () after has_chunks I made some adjustments to my python. I no longer get an error but now it seems I have no chunk data in my buffer.

Could still use some guidance if anyone sees what I am doing incorrectly.


# Create chunk parser
chunk_parser = camera.create_chunk_parser()
  
# Enable chunk data: Timestamp
if camera.are_chunks_available():
    camera.set_chunks("Timestamp")
    
    #Confirm
    if camera.get_chunk_mode():
        print("Chunk mode confirmed.")
        
        if camera.get_chunk_state("Timestamp"):
            print("Timestamp enabled.")
    else:
        print("Failed to confirm chunk mode.")
else:
    print("Chunk data not available for this camera")

payload = camera.get_payload ()
[x,y,width,height] = camera.get_region ()

# Print camera info
print ("Camera vendor : %s" %(camera.get_vendor_name ()))
print ("Camera model  : %s" %(camera.get_model_name ()))
print ("ROI           : %dx%d at %d,%d" %(width, height, x, y))
print ("Payload       : %d" %(payload))
print ("Pixel format  : %s" %(camera.get_pixel_format_as_string ()))

stream = camera.create_stream (None, None)

# Create a buffer for capture
stream.push_buffer(Aravis.Buffer.new_allocate (payload))

print ("Starting...")
camera.start_acquisition ()

#Enter main loop to gather frame and chunk data and print data to screen
try:
    for i in range(0,5):
        # Get the buffer
        buffer = stream.pop_buffer ()
        
        if buffer:
            # If the image has chunk data lets handle it. 
            if buffer.has_chunks():
                ts = chunk_parser.get_float_value(buffer, "Timestamp")
                print("Timestamp: ", ts)
            else:
                print("No chunk data.")
            stream.push_buffer (buffer)
        else:
            print("No buffer.")
            
except Exception as error:
    print(error)

finally:
    print ("Stopping.")
    camera.stop_acquisition ()

The resulting output:

root@imx8qm:/test/bin# python3 arv-chunk-test.py
Software trigger available. Attempting to configure...
Software trigger confirmed.
Chunk mode confirmed.
Timestamp enabled.
Camera vendor : FLIR
Camera model  : Blackfly S BFS-U3-120S4C
ROI           : 128x128 at 0,0
Payload       : 16420
Pixel format  : Mono8
Starting...
No chunk data.
No chunk data.
No chunk data.
No chunk data.
No chunk data.
Stopping.

If anyone happens to come looking for an answer for this, I finally solved it.

The script I had was actually very close. The issue was this line:

ts = chunk_parser.get_float_value(buffer, "Timestamp")

For Aravis, when getting chunk data, you must specify “Chunk” in front of the item you are wishing the parser to grab.

In my case the solution was this and notice integer instead of float because the output is…an integer:

ts = chunk_parser.get_integer_value(image, "ChunkTimestamp")

Hopefully this helps somebody one day because the documentation was not clear on this.

# Enter main loop to gather frame and chunk data and print data to screen
    # For now, just a temp 10 count loop to show usage.
    try:
        for i in range(0,10):
            # Squeeze trigger to capture image if sw_trigger enabled
            if sw_trigger:
                camera.software_trigger()
            # Get the buffer
            image = stream.pop_buffer()
            
            print(image)
            
            if image:
                # If the image has chunk data lets handle it. 
                if image.has_chunks():
                    cts = chunk_parser.get_integer_value(image, "ChunkTimestamp")
                    cw = chunk_parser.get_integer_value(image, "ChunkWidth")
                    ch = chunk_parser.get_integer_value(image, "ChunkHeight")
                    print("Timestamp: {}, Width: {}, Height: {}".format(cts, cw, ch))
                else:
                    print("No chunk data.")
                    
                # Make space for a new frame
                stream.push_buffer(image)
            else:
                print("No image.")
                
    except Exception as error:
        print(error)

    finally:
        print ("Stopping.")
        camera.stop_acquisition ()

Hi,

Thanks for the follow-up. I will add a word about feature naming for the chunk parser in the documentation.

May be aravis could automatically add the Chunk prefix, but I’m not sure it is mandatory.

Emmanuel.