[libcamera-devel] [PATCH v5 04/13] py: cam.py: Use new events support

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Jun 5 07:10:28 CEST 2023


Hi Tomi,

Thank you for the patch.

On Sat, Jun 03, 2023 at 10:56:06AM +0300, Tomi Valkeinen wrote:
> Convert cam.py to use the new event dispatching. In addition to handling
> the request-completed event, handle also disconnect, camera-added and
> camera-removed events (which only do a simple print).
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
>  src/py/cam/cam.py | 27 +++++++++++++++++++++------
>  1 file changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/src/py/cam/cam.py b/src/py/cam/cam.py
> index a2a115c1..1e2d1f69 100755
> --- a/src/py/cam/cam.py
> +++ b/src/py/cam/cam.py
> @@ -230,11 +230,19 @@ class CaptureState:
>      # Called from renderer when there is a libcamera event
>      def event_handler(self):
>          try:
> -            reqs = self.cm.get_ready_requests()
> -
> -            for req in reqs:
> -                ctx = next(ctx for ctx in self.contexts if ctx.idx == req.cookie)
> -                self.__request_handler(ctx, req)
> +            for ev in self.cm.get_events():
> +                type = ev.type
> +
> +                if type == libcam.Event.Type.CameraAdded:
> +                    print(f'Camera {ev.camera} added')
> +                elif type == libcam.Event.Type.CameraRemoved:
> +                    print(f'Camera {ev.camera} removed')
> +                elif type == libcam.Event.Type.Disconnect:
> +                    print(f'Camera {ev.camera} disconnected')
> +                elif type == libcam.Event.Type.RequestCompleted:
> +                    self.__request_handler(ev.camera, ev.request)
> +                else:
> +                    raise RuntimeError("Bad event type")

This will cause issues if we later add new event types. Wouldn't it be
better to ignore unknown event types, or possibly print a (one-time)
warning message ?

>  
>              running = any(ctx.reqs_completed < ctx.opt_capture for ctx in self.contexts)
>              return running
> @@ -242,7 +250,9 @@ class CaptureState:
>              traceback.print_exc()
>              return False
>  
> -    def __request_handler(self, ctx, req):
> +    def __request_handler(self, cam, req):
> +        ctx = next(ctx for ctx in self.contexts if ctx.camera == cam)
> +
>          if req.status != libcam.Request.Status.Complete:
>              raise Exception('{}: Request failed: {}'.format(ctx.id, req.status))
>  
> @@ -447,6 +457,11 @@ def main():
>  
>          state.do_cmd_capture()
>  
> +        # This is not strictly needed, but it helps to do a proper cleanup as we
> +        # drop any unhandled events, and so makes it easier to use memory leak
> +        # detectors.
> +        cm.get_events()

Somehow this feels like a hack, outlining a design issue. Is there any
way we could do better ? How about clearing events in the camera manager
destructor ?

> +
>      return 0
>  
>  

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list