Error when using multistreams, stream.engine_start

I am receiving this error when trying to get multiple streams.


An example of the code I am using is below;

import cvb

def discovery():
    devices = cvb.DeviceFactory.discover_from_root(cvb.DiscoverFlags.IgnoreVins)
    ret = {}
    for discover in devices:
        try:
            device = cvb.DeviceFactory.open(discover.access_token, cvb.AcquisitionStack.GenTL)
            dnm = device.node_maps["Device"]
            name = dnm["DeviceVendorName"].value + " - " + dnm["DeviceModelName"].value
            if name in ret: continue
            print(dnm["DeviceVendorName"].value)
            print(dnm["DeviceModelName"].value)
            print(dnm["DeviceVersion"].value)
            ret[name] = discover.access_token
        except:
            pass
    return ret

class recording_GUI:
    def __init__(self):
        
        self.cams = discovery()
        self.setup_streams()
    
    def setup_streams(self):
        self.streams = []
        self.stream_names = []
        for cam in self.cams:
            with cvb.DeviceFactory.open(self.cams[cam], cvb.AcquisitionStack.GenTL) as device:
                for i in range(device.stream_count):
                    self.streams.append(device.stream(cvb.ImageStream, i))
                    self.stream_names.append(cam + " " + str(i))
        for stream in self.streams:
            stream.engine_start()
            stream.device_start()

if __name__ == "__main__":
    x = recording_GUI()

Why is this error occurring and how do I solve it?

Hi @Aaron00

does this error also occur, when you do not spilt your program into two classes?

Hi @Chris
Thanks for responding. I’ve taken out the classes and I am still getting the same error as above.
This is the code without the classes:

import cvb

def discovery():
    devices = cvb.DeviceFactory.discover_from_root(cvb.DiscoverFlags.IgnoreVins)
    ret = {}
    for discover in devices:
        try:
            device = cvb.DeviceFactory.open(discover.access_token, cvb.AcquisitionStack.GenTL)
            dnm = device.node_maps["Device"]
            name = dnm["DeviceVendorName"].value + " - " + dnm["DeviceModelName"].value
            if name in ret: continue
            print(dnm["DeviceVendorName"].value)
            print(dnm["DeviceModelName"].value)
            print(dnm["DeviceVersion"].value)
            ret[name] = discover.access_token
        except:
            pass
    return ret
    
def setup_streams(cams):
    streams = []
    stream_names = []
    for cam in cams:
        with cvb.DeviceFactory.open(cams[cam], cvb.AcquisitionStack.GenTL) as device:
            for i in range(device.stream_count):
                streams.append(device.stream(cvb.ImageStream, i))
                stream_names.append(cam + " " + str(i))
    for stream in streams:
        stream.engine_start()
        stream.device_start()

if __name__ == "__main__":
    cams = discovery()
    setup_streams(cams)

So do I get this right, that even without creating an object of the GUI class, you are still getting the error?
I would have assumed, that the UI has its own UI thread context and as Py is a bit tricky with multiple threads, this was what might have caused an error.

But in your recently postet code this does not seem to be the case.

Yes, we ran the exact code that we’ve posted here. We get the same error.

Not entirely sure what you mean by threading; we’re not using any threading in our code at this time. Is this an inherent python thing?

When creating the code, did you copy from one of our examples.

From looking into the documentation I am not sure if you might need to start the device before staring the engine, thats why I ask.

Yes, this was based off of the following example: Common Vision Blox: Migration Guide for the Acquisition Stacks

We’ve just tried switching the engine_start/device_start functions, this produces the same error.

Try to remove the append functionality with the generator pattern as used in the migration guide:

streams = [device.stream(ImageStream, i) for i in range(device.stream_count)] # (1)

This has had no effect.

Ok I will try to reproduce the error with your code tomorrow.
Until then, does the example of the migration guide work for you if left unchanged?

It does not produce the same error. Will test to make sure it fully works

I think this would be the best way… start with the example and piece by piece abstract your way to where it fails, then we might be able to find out what causes this behaviour but for know I puzzled as well.
As mentioned bevore I will try this tomorrow, if you have any news bevore me let me know.

Hi @Aaron00
let me know once you have tested the code from the migration guide so we can avoid doing the same work twice.

Cheers
Chris

Hi @Chris,
I have tested the code from the migration guide and it works shown below:
import cvb

devices = cvb.DeviceFactory.discover_from_root(cvb.DiscoverFlags.IgnoreVins)
with cvb.DeviceFactory.open(devices[0].access_token, cvb.AcquisitionStack.GenTL) as device:
streams = [device.stream(cvb.ImageStream, i) for i in range(device.stream_count)] # (1)
for stream in streams:
stream.engine_start() # (2)
for stream in streams:
stream.device_start() # (3)
for _ in range(10):
images = [stream.wait() for stream in streams]
try:
pass
finally:
for image, status, nodes in images:
with image:
pass
for stream in streams:
stream.device_abort()
for stream in streams:
stream.engine_abort()

So the best way would be to change this code to do what you like and test if it fails with every major change.
This is very likely a Python related “feature” and not a CVB Bug.

Cheers
Chris