• Christopher Cameron's avatar
    Mac Zero Copy Capture: Allow external GMB reuse · b7a84d31
    Christopher Cameron authored
    The capture system is built around the assumption that the
    VideoCaptureBufferPool allocates buffers and manages their lifetime.
    This does not match the behavior on macOS where the macOS capture
    APIs manage buffer pools (via a CVPixelBufferPool).
    
    Prior to this change, these "external" buffers were not tracked by the
    VideoCaptureBufferPool beyond having an id assigned for them. They
    were never "reused" -- every new frame was treated as though it was
    a new buffer. This was problematic because it caused these buffers
    to be opened and closed as they propagated through three processes
    (the capture, renderer, and GPU process), burning lots of CPU. In fact,
    the underlying IOSurfaces are indeed reused in the CVPixelBufferPool.
    
    This patch enables VideoCaptureBufferPool to exploit the IOSurface
    reuse done by the CVPixelBufferPool. It uses GpuMemoryBufferTrackerMac
    to track the externally-provided buffers. When a new IOSurface is
    presented in VideoCaptureDeviceClient::OnIncomingCapturedExternalBuffer,
    the function VideoCaptureBufferPoolImpl::ReserveIdForExternalBuffer
    uses the new IsSameGpuMemoryBuffer function to determine if we are
    already tracking the GpuMemoryBuffer.
    
    Of note is that VideoCaptureBufferPoolImpl::ReserveIdForExternalBuffer
    uses LRU order to discard old buffers (which matches the
    CVPixelBufferPool usage pattern), while the other function that does
    this, VideoCaptureBufferPoolImpl::ReserveForProducerInternal, finds
    the largest buffer to discard.
    
    To prevent the CVPixelBufferPool from reclaiming the IOSurface before
    the consumer is done with it, add a OnHeldByConsumersChanged function
    which calls IOSurfaceIncrementUseCount (via gfx::ScopedInUseIOSurface)
    to signal to the CVPixelBufferPool that the IOSurface can't be
    reclaimed yet. This involves some refactoring of the
    VideoCaptureBufferTracker class.
    
    Prior to this patch, the IOSurface's in use count was being updated
    by the ScopedAccessPermission argument provided to the
    VideoCaptureDeviceClient::OnIncomingCapturedExternalBuffer function.
    Just drop that ScopedAccessPermission on the floor for now -- it will
    be cleaned up in a follow-on patch (this one is already big).
    
    Update tests to test this.
    
    Bug: 1125879
    Change-Id: I9eaf6dd47126103b094f54bf23a3f28cf2318d62
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2493089Reviewed-by: default avatarMarkus Handell <handellm@google.com>
    Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
    Commit-Queue: ccameron <ccameron@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#821837}
    b7a84d31
video_capture_buffer_pool_impl.cc 9.6 KB