Files
RetroArch/camera
U-DESKTOP-SPFP6AQ\twistedtechre f3b3d69fcb camera/avfoundation: reuse frameBuffer for color-bars fallback, null after free
Audit of the frameBuffer lifecycle turned up three small issues in
camera/drivers/avfoundation.m that all cluster around the same ivar:

  1. avfoundation_init's setupCameraSession-failed error path does
     free(avf->manager.frameBuffer) but does not null the field.
     The manager is a singleton, so the next avfoundation_init
     inherits a dangling pointer until its own calloc overwrites
     the slot. Everything in this driver runs on the main thread
     (capture delegate queue is dispatch_get_main_queue(), poll
     runs from rarch_draw_observer on the main run loop, init/free
     are on the main thread) so no concurrent access can observe
     the dangling value - but it is still defensive-programming-
     wrong to leave a singleton ivar pointing at freed memory.

  2. avfoundation_poll's color-bars fallback calloc'd and freed a
     throwaway buffer on every poll while the camera session was
     warming up or stopped. For a typical 1280x720 camera that is
     ~3.5 MB of allocator churn per poll, fired at runloop rate
     until the session reports isRunning. Since we already have
     a cached per-driver frameBuffer on the manager (allocated in
     init, size matches avf->width x avf->height exactly), paint
     the color-bars pattern directly into it and hand that to
     frame_raw_cb. The captureOutput callback will overwrite the
     same buffer with real camera frames once the session starts.

  3. The 'Camera not running, generating color bars...' log at the
     top of that fallback path fires every poll during the warmup
     window - the same per-frame log-spam pattern that commit
     141d2a6 already fixed for two other logs in the file. Gate
     this one behind #ifdef DEBUG to match.

Threading model (unchanged): the capture delegate is invoked on the
main queue (set via setSampleBufferDelegate:queue: to
dispatch_get_main_queue()) and the consumer of frameBuffer reads on
the main thread as well (runloop_iterate runs from a
CFRunLoopObserver attached to CFRunLoopGetMain() on macOS, from
CADisplayLink on iOS/tvOS - both main-thread). Writer and reader
are fully serialized by the main run loop, so reuse of frameBuffer
across both paths needs no additional synchronization.
2026-04-23 19:26:32 +02:00
..
2026-03-28 22:40:24 -04:00