gstreamer 1.20: v4l2bufferpool spams "newly allocated buffer is not free"

Nicolas Dufresne nicolas at ndufresne.ca
Thu Jun 30 16:04:29 UTC 2022


Le jeudi 30 juin 2022 à 11:37 -0400, Nicolas Dufresne a écrit :
> Le mardi 28 juin 2022 à 22:53 +0200, Michiel Konstapel via gstreamer-devel a
> écrit :
> > On 28-06-2022 22:13, Michiel Konstapel wrote:
> > > On 27-06-2022 22:24, Nicolas Dufresne via gstreamer-devel wrote:
> > > > Le dimanche 26 juin 2022 à 14:30 +0200, Michiel Konstapel a écrit :
> > > > > On 25-06-2022 17:34, Nicolas Dufresne via gstreamer-devel wrote:
> > > > > > > It's a very common Logitech C920 webcam (but I've seen the same 
> > > > > > > message
> > > > > > > with a Z-Cam M3 camera). I think that uses a generic UVC driver? 
> > > > > > > Anything
> > > > > > > I can run to get you more info?
> > > > > > > 
> > > > > > I'm asking as I cannot reproduce, and from the look of it, the 
> > > > > > trace implies
> > > > > > is will leak data. Which Kernel? Have you tested with your own 
> > > > > > GStreamer
> > > > > > build (main branch)?
> > > > > $ uname -a
> > > > >   Linux xubuntux 5.4.0-121-generic #137-Ubuntu SMP Wed Jun 15 
> > > > > 13:33:07 UTC 2022
> > > > That might explain the discrepancy, this is an old kernel, its quite 
> > > > likely this
> > > > is a kernel bug and its fixed in newer kernels. Make sure to try more 
> > > > recently
> > > > Ubuntu and check. If it is, you likely can request a backport to Ubuntu,
> > > > assuming this isn't an EOL version you are using.
> > > > 
> > > > > x86_64 x86_64 x86_64 GNU/Linux
> > > > > Gstreamer is built from source, from the 1.20.3 tag.
> > > > > I have also just built it from main (commit
> > > > > 0e551871c45a1b9fd67d99d2d4f31a983f1b3217) and that shows the effect 
> > > > > as well.
> > > > > Michiel
> > > 
> > > Alas, not quite. I've upgraded to Ubuntu 22.04 which has
> > > 
> > > $ uname -a
> > > Linux xubuntux 5.15.0-40-generic #43-Ubuntu SMP Wed Jun 15 12:54:21 
> > > UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
> > > 
> > > But the problem persists.
> > 
> > 
> > Another data point: I have another video device, on /dev/video0, which 
> > is the webcam inside my Valve Index VR headset. That one does NOT 
> > produce the warnings! I tried unplugging the headset and replugging the 
> > Logitech C920 so that's on /dev/video0 (and the only webcam) but that 
> > doesn't help: it still spews warnings.
> > 
> 
> I'd be curious to see the value or &pool->buffer_state[group->buffer.index] when
> that warning triggers. I fail to see how we actually endup in that situation. I
> wonder if there is a relation with:
> 
> https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1087
> 
> And associated merge request. Did you already tried ?
> 
> https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2007

Looking deeper, it might just a minor bug, and not something as problematic as
above. I can't say why, but what I believe happens is that after v4l2src pushed
the buffer, it get release, but it is now invalid:


static void
gst_v4l2_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer)
{
  GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
  GstV4l2MemoryGroup *group;
  gboolean queued = FALSE;

  if (gst_v4l2_is_buffer_valid (buffer, &group)) {
    gint old_buffer_state =
        g_atomic_int_and (&pool->buffer_state[group->buffer.index],
        ~BUFFER_STATE_OUTSTANDING);
    queued = (old_buffer_state & BUFFER_STATE_QUEUED) != 0;
    GST_LOG_OBJECT (pool, "mark buffer %u not outstanding",
        group->buffer.index);
  }

  gst_v4l2_buffer_pool_complete_release_buffer (bpool, buffer, queued);
}

Not "valid buffer" simply means it was modified in a way we could not find back
which GstV4l2MemoryGroup is was associated with. Without the group, we can't
know the buffer index, hence we can't clear the outstanding state.

Later on, the group will be released to the allocator, which the pool is aware
as it registered a callback 

    pool->group_released_handler =
        g_signal_connect_swapped (pool->vallocator, "group-released",
        G_CALLBACK (gst_v4l2_buffer_pool_resurrect_buffer), pool);


But the callback only say that "a group" was released, it does not say which
one. And we have currently no mean to clear the OUTSTANDING flag, which
eventually leads us to think we just allocated an outstanding buffer. Now that I
understand how this is possible, it might be possible to fix it. Though I can
confirm it will have no side effect other then this spammy trace.

Nicolas


More information about the gstreamer-devel mailing list